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> --- strbuf.c | 23 +++++++++++++++++++---- strbuf.h | 3 ++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/strbuf.c b/strbuf.c index a6153dc..2bbc49c 100644 --- a/strbuf.c +++ b/strbuf.c @@ -214,25 +214,40 @@ 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; 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 ((ssize_t) 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, diff --git a/strbuf.h b/strbuf.h index d05e056..e602899 100644 --- a/strbuf.h +++ b/strbuf.h @@ -109,8 +109,9 @@ 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 size_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; -- 1.6.5.99.g9ed7e -- 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