Use split_ident_line to parse author and committer

Currently blame.c::get_acline(), pretty.c::pp_user_info() and shortlog.c::insert_one_record() are parsing author name, email, time and tz themselves. Use ident.c::split_ident_line() for better code reuse. 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 3c020bd528d5dc320b82bd787670edfe6695f097
3 files changed +52 -78
builtin/blame.c
+21 -38
@@ -1343,8 +1343,9 @@ static void get_ac_line(const char *inbuf, const char *what,
1343 int mail_len, char *mail,
1344 unsigned long *time, const char **tz)
1345 {
1346 - int len, tzlen, maillen;
1347 - char *tmp, *endp, *timepos, *mailpos;
1346 + struct ident_split ident;
1347 + int len, tzlen, maillen, namelen;
1348 + char *tmp, *endp, *mailpos;
1349
1350 tmp = strstr(inbuf, what);
1351 if (!tmp)
@@ -1355,7 +1356,10 @@ static void get_ac_line(const char *inbuf, const char *what,
1356 len = strlen(tmp);
1357 else
1358 len = endp - tmp;
1358 - if (person_len <= len) {
1359 + if (person_len <= len)
1360 + goto error_out;
1361 +
1362 + if (split_ident_line(&ident, tmp, len)) {
1363 error_out:
1364 /* Ugh */
1365 *tz = "(unknown)";
@@ -1364,47 +1368,26 @@ static void get_ac_line(const char *inbuf, const char *what,
1368 *time = 0;
1369 return;
1370 }
1367 - memcpy(person, tmp, len);
1371
1369 - tmp = person;
1370 - tmp += len;
1371 - *tmp = 0;
1372 - while (person < tmp && *tmp != ' ')
1373 - tmp--;
1374 - if (tmp <= person)
1375 - goto error_out;
1376 - *tz = tmp+1;
1377 - tzlen = (person+len)-(tmp+1);
1372 + namelen = ident.name_end - ident.name_begin;
1373 + memcpy(person, ident.name_begin, namelen);
1374 + person[namelen] = 0;
1375
1379 - *tmp = 0;
1380 - while (person < tmp && *tmp != ' ')
1381 - tmp--;
1382 - if (tmp <= person)
1383 - goto error_out;
1384 - *time = strtoul(tmp, NULL, 10);
1385 - timepos = tmp;
1376 + maillen = ident.mail_end - ident.mail_begin + 2;
1377 + memcpy(mail, ident.mail_begin - 1, maillen);
1378 + mail[maillen] = 0;
1379
1387 - *tmp = 0;
1388 - while (person < tmp && !(*tmp == ' ' && tmp[1] == '<'))
1389 - tmp--;
1390 - if (tmp <= person)
1391 - return;
1392 - mailpos = tmp + 1;
1393 - *tmp = 0;
1394 - maillen = timepos - tmp;
1395 - memcpy(mail, mailpos, maillen);
1380 + *time = strtoul(ident.date_begin, NULL, 10);
1381
1397 - if (!mailmap.nr)
1398 - return;
1382 + tzlen = ident.tz_end - ident.tz_begin;
1383
1400 - /*
1401 - * mailmap expansion may make the name longer.
1402 - * make room by pushing stuff down.
1403 - */
1404 - tmp = person + person_len - (tzlen + 1);
1405 - memmove(tmp, *tz, tzlen);
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;
1407 - *tz = tmp;
1388 +
1389 + if (!mailmap.nr)
1390 + return;
1391
1392 /*
1393 * Now, convert both name and e-mail using mailmap
builtin/shortlog.c
+10 -26
@@ -40,40 +40,24 @@ static void insert_one_record(struct shortlog *log,
40 char emailbuf[1024];
41 size_t len;
42 const char *eol;
43 - const char *boemail, *eoemail;
43 struct strbuf subject = STRBUF_INIT;
44 + struct ident_split ident;
45
46 - boemail = strchr(author, '<');
47 - if (!boemail)
48 - return;
49 - eoemail = strchr(boemail, '>');
50 - if (!eoemail)
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 */
54 - memcpy(namebuf, author, boemail - author);
55 - len = boemail - author;
56 - while (len > 0 && isspace(namebuf[len-1]))
57 - len--;
50 + len = ident.name_end - ident.name_begin;
51 + memcpy(namebuf, ident.name_begin, len);
52 namebuf[len] = 0;
53
54 /* copy email name to emailbuf, to allow email replacement as well */
61 - memcpy(emailbuf, boemail+1, eoemail - boemail);
62 - emailbuf[eoemail - boemail - 1] = 0;
63 -
64 - if (!map_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf))) {
65 - while (author < boemail && isspace(*author))
66 - author++;
67 - for (len = 0;
68 - len < sizeof(namebuf) - 1 && author + len < boemail;
69 - len++)
70 - namebuf[len] = author[len];
71 - while (0 < len && isspace(namebuf[len-1]))
72 - len--;
73 - namebuf[len] = '\0';
74 - }
75 - else
76 - len = strlen(namebuf);
55 + len = ident.mail_end - ident.mail_begin;
56 + memcpy(emailbuf, ident.mail_begin, len);
57 + emailbuf[len] = 0;
58 +
59 + map_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf));
60 + len = strlen(namebuf);
61
62 if (log->email) {
63 size_t room = sizeof(namebuf) - len - 1;
pretty.c
+21 -14
@@ -387,29 +387,36 @@ void pp_user_info(const struct pretty_print_context *pp,
387 const char *what, struct strbuf *sb,
388 const char *line, const char *encoding)
389 {
390 + struct ident_split ident;
391 + int linelen, namelen;
392 + char *line_end, *date;
393 int max_length = 78; /* per rfc2822 */
391 - char *date;
392 - int namelen;
394 unsigned long time;
395 int tz;
396
397 if (pp->fmt == CMIT_FMT_ONELINE)
398 return;
398 - date = strchr(line, '>');
399 - if (!date)
399 +
400 + line_end = strchr(line, '\n');
401 + if (!line_end) {
402 + line_end = strchr(line, '\0');
403 + if (!line_end)
404 + return;
405 + }
406 +
407 + linelen = ++line_end - line;
408 + if (split_ident_line(&ident, line, linelen))
409 return;
401 - namelen = ++date - line;
402 - time = strtoul(date, &date, 10);
410 +
411 + namelen = ident.mail_end - ident.name_begin + 1;
412 + time = strtoul(ident.date_begin, &date, 10);
413 tz = strtol(date, NULL, 10);
414
415 if (pp->fmt == CMIT_FMT_EMAIL) {
406 - char *name_tail = strchr(line, '<');
416 int display_name_length;
408 - if (!name_tail)
409 - return;
410 - while (line < name_tail && isspace(name_tail[-1]))
411 - name_tail--;
412 - display_name_length = name_tail - line;
417 +
418 + display_name_length = ident.name_end - ident.name_begin;
419 +
420 strbuf_addstr(sb, "From: ");
421 if (needs_rfc2047_encoding(line, display_name_length, RFC2047_ADDRESS)) {
422 add_rfc2047(sb, line, display_name_length,
@@ -427,10 +434,10 @@ void pp_user_info(const struct pretty_print_context *pp,
434 }
435 if (namelen - display_name_length + last_line_length(sb) > max_length) {
436 strbuf_addch(sb, '\n');
430 - if (!isspace(name_tail[0]))
437 + if (!isspace(ident.name_end[0]))
438 strbuf_addch(sb, ' ');
439 }
433 - strbuf_add(sb, name_tail, namelen - display_name_length);
440 + strbuf_add(sb, ident.name_end, namelen - display_name_length);
441 strbuf_addch(sb, '\n');
442 } else {
443 strbuf_addf(sb, "%s: %.*s%.*s\n", what,