From e2b239722a5806521016835f86e6c29c630a0e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Wed, 7 Sep 2011 13:46:08 -0400 Subject: for-each-ref: add split message parts to %(contents:*). The %(body) placeholder returns the whole body of a tag or commit, including the signature. However, callers may want to get just the body without signature, or just the signature. Rather than change the meaning of %(body), which might break some scripts, this patch introduces a new set of placeholders which break down the %(contents) placeholder into its constituent parts. [jk: initial patch by mg, rebased on top of my refactoring and with tests by me] Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/for-each-ref.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'builtin/for-each-ref.c') diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index ea2112b388..d90e5d2b29 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -69,6 +69,9 @@ static struct { { "subject" }, { "body" }, { "contents" }, + { "contents:subject" }, + { "contents:body" }, + { "contents:signature" }, { "upstream" }, { "symref" }, { "flag" }, @@ -472,7 +475,9 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru static void find_subpos(const char *buf, unsigned long sz, const char **sub, unsigned long *sublen, - const char **body, unsigned long *bodylen) + const char **body, unsigned long *bodylen, + unsigned long *nonsiglen, + const char **sig, unsigned long *siglen) { const char *eol; /* skip past header until we hit empty line */ @@ -486,10 +491,14 @@ static void find_subpos(const char *buf, unsigned long sz, while (*buf == '\n') buf++; + /* parse signature first; we might not even have a subject line */ + *sig = buf + parse_signature(buf, strlen(buf)); + *siglen = strlen(*sig); + /* subject is first non-empty line */ *sub = buf; /* subject goes to first empty line */ - while (*buf && *buf != '\n') { + while (buf < *sig && *buf && *buf != '\n') { eol = strchrnul(buf, '\n'); if (*eol) eol++; @@ -505,14 +514,15 @@ static void find_subpos(const char *buf, unsigned long sz, buf++; *body = buf; *bodylen = strlen(buf); + *nonsiglen = *sig - buf; } /* See grab_values */ static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz) { int i; - const char *subpos = NULL, *bodypos; - unsigned long sublen, bodylen; + const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL; + unsigned long sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0; for (i = 0; i < used_atom_cnt; i++) { const char *name = used_atom[i]; @@ -523,17 +533,27 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj name++; if (strcmp(name, "subject") && strcmp(name, "body") && - strcmp(name, "contents")) + strcmp(name, "contents") && + strcmp(name, "contents:subject") && + strcmp(name, "contents:body") && + strcmp(name, "contents:signature")) continue; if (!subpos) find_subpos(buf, sz, &subpos, &sublen, - &bodypos, &bodylen); + &bodypos, &bodylen, &nonsiglen, + &sigpos, &siglen); if (!strcmp(name, "subject")) v->s = copy_subject(subpos, sublen); + else if (!strcmp(name, "contents:subject")) + v->s = copy_subject(subpos, sublen); else if (!strcmp(name, "body")) v->s = xmemdupz(bodypos, bodylen); + else if (!strcmp(name, "contents:body")) + v->s = xmemdupz(bodypos, nonsiglen); + else if (!strcmp(name, "contents:signature")) + v->s = xmemdupz(sigpos, siglen); else if (!strcmp(name, "contents")) v->s = xstrdup(subpos); } -- cgit v1.2.3