Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-07-06 21:54:45 +0300
committerJunio C Hamano <gitster@pobox.com>2023-07-06 21:54:45 +0300
commitda269af9207e38e820daad8aa993caa7d2fad76c (patch)
tree28567788ed00e6c037cb93684e95a473e3d2f412 /builtin/ls-tree.c
parenta646b86cd10282de2ceb64ef33b5412e4fb2a54c (diff)
parent4416b86c6b34dad64b556bb1eb6711d5e6595a48 (diff)
Merge branch 'rs/strbuf-expand-step'
Code clean-up around strbuf_expand() API. * rs/strbuf-expand-step: strbuf: simplify strbuf_expand_literal_cb() replace strbuf_expand() with strbuf_expand_step() replace strbuf_expand_dict_cb() with strbuf_expand_step() strbuf: factor out strbuf_expand_step() pretty: factor out expand_separator()
Diffstat (limited to 'builtin/ls-tree.c')
-rw-r--r--builtin/ls-tree.c107
1 files changed, 41 insertions, 66 deletions
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 4e17f13648..7a062e2b67 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(&sb, format)))
+ 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);