From: René Scharfe Date: Sat, 17 Jun 2023 20:41:44 +0000 (+0200) Subject: strbuf: factor out strbuf_expand_step() X-Git-Tag: v2.42.0-rc0~73^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=44ccb337f10a08bb265b911f86deaf5f3347d967;p=thirdparty%2Fgit.git strbuf: factor out strbuf_expand_step() Extract the part of strbuf_expand that finds the next placeholder into a new function. It allows to build parsers without callback functions and the overhead imposed by them. Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- diff --git a/builtin/branch.c b/builtin/branch.c index e6c2655af6..7c20e049a2 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -366,17 +366,8 @@ static const char *quote_literal_for_format(const char *s) static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - while (*s) { - const char *ep = strchrnul(s, '%'); - if (s < ep) - strbuf_add(&buf, s, ep - s); - if (*ep == '%') { - strbuf_addstr(&buf, "%%"); - s = ep + 1; - } else { - s = ep; - } - } + while (strbuf_expand_step(&buf, &s)) + strbuf_addstr(&buf, "%%"); return buf.buf; } diff --git a/strbuf.c b/strbuf.c index 08eec8f1d8..a90b597da1 100644 --- a/strbuf.c +++ b/strbuf.c @@ -415,19 +415,24 @@ void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap) strbuf_setlen(sb, sb->len + len); } +int strbuf_expand_step(struct strbuf *sb, const char **formatp) +{ + const char *format = *formatp; + const char *percent = strchrnul(format, '%'); + + strbuf_add(sb, format, percent - format); + if (!*percent) + return 0; + *formatp = percent + 1; + return 1; +} + void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context) { - for (;;) { - const char *percent; + while (strbuf_expand_step(sb, &format)) { size_t consumed; - percent = strchrnul(format, '%'); - strbuf_add(sb, format, percent - format); - if (!*percent) - break; - format = percent + 1; - if (*format == '%') { strbuf_addch(sb, '%'); format++; @@ -1022,12 +1027,7 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm, * we want for %z, but the computation for %s has to convert to number * of seconds. */ - for (;;) { - const char *percent = strchrnul(fmt, '%'); - strbuf_add(&munged_fmt, fmt, percent - fmt); - if (!*percent) - break; - fmt = percent + 1; + while (strbuf_expand_step(&munged_fmt, &fmt)) { switch (*fmt) { case '%': strbuf_addstr(&munged_fmt, "%%"); diff --git a/strbuf.h b/strbuf.h index 3dfeadb44c..a189f12b84 100644 --- a/strbuf.h +++ b/strbuf.h @@ -371,6 +371,14 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context); +/** + * If the string pointed to by `formatp` contains a percent sign ("%"), + * advance it to point to the character following the next one and + * return 1, otherwise return 0. Append the substring before that + * percent sign to `sb`, or the whole string if there is none. + */ +int strbuf_expand_step(struct strbuf *sb, const char **formatp); + /** * Append the contents of one strbuf to another, quoting any * percent signs ("%") into double-percents ("%%") in the