From 6f1e2d52797161c7effe4d1388765de3dbd80bbf Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Sat, 17 Jun 2023 22:43:17 +0200 Subject: replace strbuf_expand() with strbuf_expand_step() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid the overhead of passing context to a callback function of strbuf_expand() by using strbuf_expand_step() in a loop instead. It requires explicit handling of %% and unrecognized placeholders, but is simpler, more direct and avoids void pointers. Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- builtin/ls-tree.c | 107 +++++++++++++++++++++--------------------------------- 1 file changed, 41 insertions(+), 66 deletions(-) (limited to 'builtin/ls-tree.c') diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 077977a461..8460d20257 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -55,63 +55,6 @@ struct ls_tree_options { const char *format; }; -struct show_tree_data { - struct ls_tree_options *options; - unsigned mode; - enum object_type type; - const struct object_id *oid; - const char *pathname; - struct strbuf *base; -}; - -static size_t expand_show_tree(struct strbuf *sb, const char *start, - void *context) -{ - struct show_tree_data *data = context; - struct ls_tree_options *options = data->options; - const char *end; - const char *p; - unsigned int errlen; - size_t len = strbuf_expand_literal_cb(sb, start, NULL); - - if (len) - return len; - if (*start != '(') - die(_("bad ls-tree format: element '%s' does not start with '('"), start); - - end = strchr(start + 1, ')'); - if (!end) - die(_("bad ls-tree format: element '%s' does not end in ')'"), start); - - len = end - start + 1; - if (skip_prefix(start, "(objectmode)", &p)) { - strbuf_addf(sb, "%06o", data->mode); - } else if (skip_prefix(start, "(objecttype)", &p)) { - strbuf_addstr(sb, type_name(data->type)); - } else if (skip_prefix(start, "(objectsize:padded)", &p)) { - expand_objectsize(sb, data->oid, data->type, 1); - } else if (skip_prefix(start, "(objectsize)", &p)) { - expand_objectsize(sb, data->oid, data->type, 0); - } else if (skip_prefix(start, "(objectname)", &p)) { - strbuf_add_unique_abbrev(sb, data->oid, options->abbrev); - } else if (skip_prefix(start, "(path)", &p)) { - const char *name = data->base->buf; - const char *prefix = options->chomp_prefix ? options->ls_tree_prefix : NULL; - struct strbuf sbuf = STRBUF_INIT; - size_t baselen = data->base->len; - - strbuf_addstr(data->base, data->pathname); - name = relative_path(data->base->buf, prefix, &sbuf); - quote_c_style(name, sb, NULL, 0); - strbuf_setlen(data->base, baselen); - strbuf_release(&sbuf); - } else { - errlen = (unsigned long)len; - die(_("bad ls-tree format: %%%.*s"), errlen, start); - } - return len; -} - static int show_recursive(struct ls_tree_options *options, const char *base, size_t baselen, const char *pathname) { @@ -150,14 +93,7 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base, int recurse = 0; struct strbuf sb = STRBUF_INIT; enum object_type type = object_type(mode); - struct show_tree_data cb_data = { - .options = options, - .mode = mode, - .type = type, - .oid = oid, - .pathname = pathname, - .base = base, - }; + const char *format = options->format; if (type == OBJ_TREE && show_recursive(options, base->buf, base->len, pathname)) recurse = READ_TREE_RECURSIVE; @@ -166,7 +102,46 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base, if (type == OBJ_BLOB && (options->ls_options & LS_TREE_ONLY)) return 0; - strbuf_expand(&sb, options->format, expand_show_tree, &cb_data); + while (strbuf_expand_step(&sb, &format)) { + const char *end; + size_t len; + + if (skip_prefix(format, "%", &format)) + strbuf_addch(&sb, '%'); + else if ((len = strbuf_expand_literal_cb(&sb, format, NULL))) + format += len; + else if (*format != '(') + die(_("bad ls-tree format: element '%s' " + "does not start with '('"), format); + else if (!(end = strchr(format + 1, ')'))) + die(_("bad ls-tree format: element '%s' " + "does not end in ')'"), format); + else if (skip_prefix(format, "(objectmode)", &format)) + strbuf_addf(&sb, "%06o", mode); + else if (skip_prefix(format, "(objecttype)", &format)) + strbuf_addstr(&sb, type_name(type)); + else if (skip_prefix(format, "(objectsize:padded)", &format)) + expand_objectsize(&sb, oid, type, 1); + else if (skip_prefix(format, "(objectsize)", &format)) + expand_objectsize(&sb, oid, type, 0); + else if (skip_prefix(format, "(objectname)", &format)) + strbuf_add_unique_abbrev(&sb, oid, options->abbrev); + else if (skip_prefix(format, "(path)", &format)) { + const char *name; + const char *prefix = options->chomp_prefix ? + options->ls_tree_prefix : NULL; + struct strbuf sbuf = STRBUF_INIT; + size_t baselen = base->len; + + strbuf_addstr(base, pathname); + name = relative_path(base->buf, prefix, &sbuf); + quote_c_style(name, &sb, NULL, 0); + strbuf_setlen(base, baselen); + strbuf_release(&sbuf); + } else + die(_("bad ls-tree format: %%%.*s"), + (int)(end - format + 1), format); + } strbuf_addch(&sb, options->null_termination ? '\0' : '\n'); fwrite(sb.buf, sb.len, 1, stdout); strbuf_release(&sb); -- cgit v1.3-6-g1900 From 4416b86c6b34dad64b556bb1eb6711d5e6595a48 Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Sat, 17 Jun 2023 22:44:00 +0200 Subject: strbuf: simplify strbuf_expand_literal_cb() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that strbuf_expand_literal_cb() is no longer used as a callback, drop its "_cb" name suffix and unused context parameter. Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- builtin/ls-files.c | 2 +- builtin/ls-tree.c | 2 +- pretty.c | 4 ++-- strbuf.c | 4 +--- strbuf.h | 6 ++---- 5 files changed, 7 insertions(+), 11 deletions(-) (limited to 'builtin/ls-tree.c') diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 03bf5771b4..0b00bd5d0f 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -274,7 +274,7 @@ static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce, if (skip_prefix(format, "%", &format)) strbuf_addch(&sb, '%'); - else if ((len = strbuf_expand_literal_cb(&sb, format, NULL))) + else if ((len = strbuf_expand_literal(&sb, format))) format += len; else if (*format != '(') die(_("bad ls-files format: element '%s' " diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 8460d20257..a90f3c81a0 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -108,7 +108,7 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base, if (skip_prefix(format, "%", &format)) strbuf_addch(&sb, '%'); - else if ((len = strbuf_expand_literal_cb(&sb, format, NULL))) + else if ((len = strbuf_expand_literal(&sb, format))) format += len; else if (*format != '(') die(_("bad ls-tree format: element '%s' " diff --git a/pretty.c b/pretty.c index cffbf32987..4c08f9856b 100644 --- a/pretty.c +++ b/pretty.c @@ -1262,7 +1262,7 @@ static struct strbuf *expand_separator(struct strbuf *sb, if (skip_prefix(format, "%", &format)) strbuf_addch(sb, '%'); - else if ((len = strbuf_expand_literal_cb(sb, format, NULL))) + else if ((len = strbuf_expand_literal(sb, format))) format += len; else strbuf_addch(sb, '%'); @@ -1395,7 +1395,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ char **slot; /* these are independent of the commit */ - res = strbuf_expand_literal_cb(sb, placeholder, NULL); + res = strbuf_expand_literal(sb, placeholder); if (res) return res; diff --git a/strbuf.c b/strbuf.c index c3d1cee616..55a3cfa5cf 100644 --- a/strbuf.c +++ b/strbuf.c @@ -427,9 +427,7 @@ int strbuf_expand_step(struct strbuf *sb, const char **formatp) return 1; } -size_t strbuf_expand_literal_cb(struct strbuf *sb, - const char *placeholder, - void *context UNUSED) +size_t strbuf_expand_literal(struct strbuf *sb, const char *placeholder) { int ch; diff --git a/strbuf.h b/strbuf.h index 95e50e243e..b1eab015f0 100644 --- a/strbuf.h +++ b/strbuf.h @@ -320,11 +320,9 @@ const char *strbuf_join_argv(struct strbuf *buf, int argc, /** * Used with `strbuf_expand_step` to expand the literals %n and %x * followed by two hexadecimal digits. Returns the number of recognized - * characters. The context argument is ignored. + * characters. */ -size_t strbuf_expand_literal_cb(struct strbuf *sb, - const char *placeholder, - void *context); +size_t strbuf_expand_literal(struct strbuf *sb, const char *placeholder); /** * If the string pointed to by `formatp` contains a percent sign ("%"), -- cgit v1.3-6-g1900