This itself does not do a "nested" expansion, but it paves a way for supporting an extended syntax to express a function that works on an expanded substring, e.g. %[function(param...)expanded-string%], by allowing the callback function to tell where the argument to the function ends. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- Dropped sloppy casts, as suggested by Dscho. pretty.c | 4 ++-- strbuf.c | 29 ++++++++++++++++++++++------- strbuf.h | 5 +++-- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/pretty.c b/pretty.c index 587101f..126be56 100644 --- a/pretty.c +++ b/pretty.c @@ -595,8 +595,8 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit) strbuf_addch(sb, ')'); } -static size_t format_commit_item(struct strbuf *sb, const char *placeholder, - void *context) +static ssize_t format_commit_item(struct strbuf *sb, const char *placeholder, + void *context) { struct format_commit_context *c = context; const struct commit *commit = c->commit; diff --git a/strbuf.c b/strbuf.c index a6153dc..af96155 100644 --- a/strbuf.c +++ b/strbuf.c @@ -214,29 +214,44 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) strbuf_setlen(sb, sb->len + len); } -void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, - void *context) +void strbuf_nested_expand(struct strbuf *sb, const char **format_p, + expand_fn_t fn, void *context) { + const char *format = *format_p; for (;;) { const char *percent; - size_t consumed; + ssize_t consumed; percent = strchrnul(format, '%'); strbuf_add(sb, format, percent - format); + format = percent; if (!*percent) break; - format = percent + 1; + format++; consumed = fn(sb, format, context); - if (consumed) + if (consumed < 0) + break; + else if (consumed) format += consumed; else strbuf_addch(sb, '%'); } + *format_p = format; +} + +void strbuf_expand(struct strbuf *sb, const char *o_format, expand_fn_t fn, + void *context) +{ + const char *format = o_format; + strbuf_nested_expand(sb, &format, fn, context); + if (*format) + die("format error: negative return from expand function: %s", + o_format); } -size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, - void *context) +ssize_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, + void *context) { struct strbuf_expand_dict_entry *e = context; size_t len; diff --git a/strbuf.h b/strbuf.h index d05e056..256d615 100644 --- a/strbuf.h +++ b/strbuf.h @@ -109,13 +109,14 @@ static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2) { } extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len); -typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context); +typedef ssize_t (*expand_fn_t)(struct strbuf *sb, const char *placeholder, void *context); extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context); +extern void strbuf_nested_expand(struct strbuf *sb, const char **format_p, expand_fn_t fn, void *context); struct strbuf_expand_dict_entry { const char *placeholder; const char *value; }; -extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context); +extern ssize_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context); __attribute__((format(printf,2,3))) extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); -- 1.6.5.1.95.g09fbd -- 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