[PATCH 2/3] strbuf_nested_expand(): allow expansion to interrupt in the middle
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:47:34
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 <redacted> --- 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