From: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> The struct pretty_print_context contains the context in which the placeholders in format_commit_one() should be parsed. Although format_commit_one() primarily acts as a parser, there is no way for a caller to plug in custom callbacks. Now, callers can: 1. Parse a custom placeholder that is not supported by format_commit_one(), and act on it independently of the pretty machinery. 2. Parse a custom placeholder to substitute the custom placeholder with a placeholder that format_commit_one() understands. This is especially useful for supporting %>(*), where * is substituted with a length computed by the caller. To support these two usecases, the interface for the function looks like: typedef size_t (*format_message_fn)(struct strbuf *sb, const char *placeholder, void *format_context, void *user_data, struct strbuf *placeholder_subst) It is exactly like format_commit_one(), except that there are two additional fields: user_data (to pass custom data to the callback), and placeholder_subst (to set the substitution). The callback should return the length of the original string parsed, and optionally set placeholder_subst. [rr: commit message, minor modifications] Signed-off-by: Ramkumar Ramachandra <artagnon@xxxxxxxxx> --- commit.h | 8 ++++++++ pretty.c | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/commit.h b/commit.h index 67bd509..04bd935 100644 --- a/commit.h +++ b/commit.h @@ -78,6 +78,12 @@ enum cmit_fmt { CMIT_FMT_UNSPECIFIED }; +typedef size_t (*format_message_fn)(struct strbuf *sb, + const char *placeholder, + void *format_context, + void *user_data, + struct strbuf *placeholder_subst); + struct pretty_print_context { enum cmit_fmt fmt; int abbrev; @@ -92,6 +98,8 @@ struct pretty_print_context { const char *output_encoding; struct string_list *mailmap; int color; + format_message_fn format; + void *user_data; }; struct userformat_want { diff --git a/pretty.c b/pretty.c index 9e43154..095e5ba 100644 --- a/pretty.c +++ b/pretty.c @@ -1069,6 +1069,31 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ struct commit_list *p; int h1, h2; + if (c->pretty_ctx->format) { + struct strbuf subst = STRBUF_INIT; + int ret = c->pretty_ctx->format(sb, placeholder, context, + c->pretty_ctx->user_data, + &subst); + if (ret && subst.len) { + /* + * Something was parsed by format(), and a + * placeholder-substitution was set. + * Recursion is required to override the + * return value of format_commit_one() with + * ret: the length of the original string + * before substitution. + */ + ret = format_commit_one(sb, subst.buf, context) ? ret : 0; + strbuf_release(&subst); + return ret; + } else if (ret) + /* + * Something was parsed by format(), but + * no placeholder-substitution was set. + */ + return ret; + } + /* these are independent of the commit */ switch (placeholder[0]) { case 'C': -- 1.8.3.GIT -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html