ident.c: add split_ident_line() to parse formatted ident line

The commit formatting logic format_person_part() in pretty.c
implements the logic to split an author/committer ident line into
its parts, intermixed with logic to compute its output using these
piece it computes.

Separate the former out to a helper function split_ident_line() so
that other codepath can use the same logic, and rewrite the function
using the helper function.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano
2012-03-11 01:25:43 -08:00
parent 0dbe6592cc
commit 4b340cfab9
3 changed files with 104 additions and 44 deletions

68
ident.c
View File

@ -220,6 +220,74 @@ static int copy(char *buf, size_t size, int offset, const char *src)
return offset;
}
/*
* Reverse of fmt_ident(); given an ident line, split the fields
* to allow the caller to parse it.
* Signal a success by returning 0, but date/tz fields of the result
* can still be NULL if the input line only has the name/email part
* (e.g. reading from a reflog entry).
*/
int split_ident_line(struct ident_split *split, const char *line, int len)
{
const char *cp;
size_t span;
int status = -1;
memset(split, 0, sizeof(*split));
split->name_begin = line;
for (cp = line; *cp && cp < line + len; cp++)
if (*cp == '<') {
split->mail_begin = cp + 1;
break;
}
if (!split->mail_begin)
return status;
for (cp = split->mail_begin - 2; line < cp; cp--)
if (!isspace(*cp)) {
split->name_end = cp + 1;
break;
}
if (!split->name_end)
return status;
for (cp = split->mail_begin; cp < line + len; cp++)
if (*cp == '>') {
split->mail_end = cp;
break;
}
if (!split->mail_end)
return status;
for (cp = split->mail_end + 1; cp < line + len && isspace(*cp); cp++)
;
if (line + len <= cp)
goto person_only;
split->date_begin = cp;
span = strspn(cp, "0123456789");
if (!span)
goto person_only;
split->date_end = split->date_begin + span;
for (cp = split->date_end; cp < line + len && isspace(*cp); cp++)
;
if (line + len <= cp || (*cp != '+' && *cp != '-'))
goto person_only;
split->tz_begin = cp;
span = strspn(cp + 1, "0123456789");
if (!span)
goto person_only;
split->tz_end = split->tz_begin + 1 + span;
return 0;
person_only:
split->date_begin = NULL;
split->date_end = NULL;
split->tz_begin = NULL;
split->tz_end = NULL;
return 0;
}
static const char *env_hint =
"\n"
"*** Please tell me who you are.\n"