Skip to content

Commit da269af

Browse files
committed
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()
2 parents a646b86 + 4416b86 commit da269af

File tree

10 files changed

+228
-366
lines changed

10 files changed

+228
-366
lines changed

builtin/branch.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -366,17 +366,8 @@ static const char *quote_literal_for_format(const char *s)
366366
static struct strbuf buf = STRBUF_INIT;
367367

368368
strbuf_reset(&buf);
369-
while (*s) {
370-
const char *ep = strchrnul(s, '%');
371-
if (s < ep)
372-
strbuf_add(&buf, s, ep - s);
373-
if (*ep == '%') {
374-
strbuf_addstr(&buf, "%%");
375-
s = ep + 1;
376-
} else {
377-
s = ep;
378-
}
379-
}
369+
while (strbuf_expand_step(&buf, &s))
370+
strbuf_addstr(&buf, "%%");
380371
return buf.buf;
381372
}
382373

builtin/cat-file.c

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,8 @@ static int is_atom(const char *atom, const char *s, int slen)
309309
}
310310

311311
static void expand_atom(struct strbuf *sb, const char *atom, int len,
312-
void *vdata)
312+
struct expand_data *data)
313313
{
314-
struct expand_data *data = vdata;
315-
316314
if (is_atom("objectname", atom, len)) {
317315
if (!data->mark_query)
318316
strbuf_addstr(sb, oid_to_hex(&data->oid));
@@ -346,19 +344,21 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
346344
die("unknown format element: %.*s", len, atom);
347345
}
348346

349-
static size_t expand_format(struct strbuf *sb, const char *start, void *data)
347+
static void expand_format(struct strbuf *sb, const char *start,
348+
struct expand_data *data)
350349
{
351-
const char *end;
352-
353-
if (*start != '(')
354-
return 0;
355-
end = strchr(start + 1, ')');
356-
if (!end)
357-
die("format element '%s' does not end in ')'", start);
358-
359-
expand_atom(sb, start + 1, end - start - 1, data);
360-
361-
return end - start + 1;
350+
while (strbuf_expand_step(sb, &start)) {
351+
const char *end;
352+
353+
if (skip_prefix(start, "%", &start) || *start != '(')
354+
strbuf_addch(sb, '%');
355+
else if (!(end = strchr(start + 1, ')')))
356+
die("format element '%s' does not end in ')'", start);
357+
else {
358+
expand_atom(sb, start + 1, end - start - 1, data);
359+
start = end + 1;
360+
}
361+
}
362362
}
363363

364364
static void batch_write(struct batch_options *opt, const void *data, int len)
@@ -495,7 +495,7 @@ static void batch_object_write(const char *obj_name,
495495
if (!opt->format) {
496496
print_default_format(scratch, data, opt);
497497
} else {
498-
strbuf_expand(scratch, opt->format, expand_format, data);
498+
expand_format(scratch, opt->format, data);
499499
strbuf_addch(scratch, opt->output_delim);
500500
}
501501

@@ -773,9 +773,8 @@ static int batch_objects(struct batch_options *opt)
773773
*/
774774
memset(&data, 0, sizeof(data));
775775
data.mark_query = 1;
776-
strbuf_expand(&output,
776+
expand_format(&output,
777777
opt->format ? opt->format : DEFAULT_FORMAT,
778-
expand_format,
779778
&data);
780779
data.mark_query = 0;
781780
strbuf_release(&output);

builtin/ls-files.c

Lines changed: 46 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -264,74 +264,57 @@ static void expand_objectsize(struct strbuf *line, const struct object_id *oid,
264264
strbuf_addstr(line, "-");
265265
}
266266
}
267-
struct show_index_data {
268-
const char *pathname;
269-
struct index_state *istate;
270-
const struct cache_entry *ce;
271-
};
272-
273-
static size_t expand_show_index(struct strbuf *sb, const char *start,
274-
void *context)
275-
{
276-
struct show_index_data *data = context;
277-
const char *end;
278-
const char *p;
279-
size_t len = strbuf_expand_literal_cb(sb, start, NULL);
280-
struct stat st;
281-
282-
if (len)
283-
return len;
284-
if (*start != '(')
285-
die(_("bad ls-files format: element '%s' "
286-
"does not start with '('"), start);
287-
288-
end = strchr(start + 1, ')');
289-
if (!end)
290-
die(_("bad ls-files format: element '%s' "
291-
"does not end in ')'"), start);
292-
293-
len = end - start + 1;
294-
if (skip_prefix(start, "(objectmode)", &p))
295-
strbuf_addf(sb, "%06o", data->ce->ce_mode);
296-
else if (skip_prefix(start, "(objectname)", &p))
297-
strbuf_add_unique_abbrev(sb, &data->ce->oid, abbrev);
298-
else if (skip_prefix(start, "(objecttype)", &p))
299-
strbuf_addstr(sb, type_name(object_type(data->ce->ce_mode)));
300-
else if (skip_prefix(start, "(objectsize:padded)", &p))
301-
expand_objectsize(sb, &data->ce->oid, object_type(data->ce->ce_mode), 1);
302-
else if (skip_prefix(start, "(objectsize)", &p))
303-
expand_objectsize(sb, &data->ce->oid, object_type(data->ce->ce_mode), 0);
304-
else if (skip_prefix(start, "(stage)", &p))
305-
strbuf_addf(sb, "%d", ce_stage(data->ce));
306-
else if (skip_prefix(start, "(eolinfo:index)", &p))
307-
strbuf_addstr(sb, S_ISREG(data->ce->ce_mode) ?
308-
get_cached_convert_stats_ascii(data->istate,
309-
data->ce->name) : "");
310-
else if (skip_prefix(start, "(eolinfo:worktree)", &p))
311-
strbuf_addstr(sb, !lstat(data->pathname, &st) &&
312-
S_ISREG(st.st_mode) ?
313-
get_wt_convert_stats_ascii(data->pathname) : "");
314-
else if (skip_prefix(start, "(eolattr)", &p))
315-
strbuf_addstr(sb, get_convert_attr_ascii(data->istate,
316-
data->pathname));
317-
else if (skip_prefix(start, "(path)", &p))
318-
write_name_to_buf(sb, data->pathname);
319-
else
320-
die(_("bad ls-files format: %%%.*s"), (int)len, start);
321-
322-
return len;
323-
}
324267

325268
static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce,
326269
const char *format, const char *fullname) {
327-
struct show_index_data data = {
328-
.pathname = fullname,
329-
.istate = repo->index,
330-
.ce = ce,
331-
};
332270
struct strbuf sb = STRBUF_INIT;
333271

334-
strbuf_expand(&sb, format, expand_show_index, &data);
272+
while (strbuf_expand_step(&sb, &format)) {
273+
const char *end;
274+
size_t len;
275+
struct stat st;
276+
277+
if (skip_prefix(format, "%", &format))
278+
strbuf_addch(&sb, '%');
279+
else if ((len = strbuf_expand_literal(&sb, format)))
280+
format += len;
281+
else if (*format != '(')
282+
die(_("bad ls-files format: element '%s' "
283+
"does not start with '('"), format);
284+
else if (!(end = strchr(format + 1, ')')))
285+
die(_("bad ls-files format: element '%s' "
286+
"does not end in ')'"), format);
287+
else if (skip_prefix(format, "(objectmode)", &format))
288+
strbuf_addf(&sb, "%06o", ce->ce_mode);
289+
else if (skip_prefix(format, "(objectname)", &format))
290+
strbuf_add_unique_abbrev(&sb, &ce->oid, abbrev);
291+
else if (skip_prefix(format, "(objecttype)", &format))
292+
strbuf_addstr(&sb, type_name(object_type(ce->ce_mode)));
293+
else if (skip_prefix(format, "(objectsize:padded)", &format))
294+
expand_objectsize(&sb, &ce->oid,
295+
object_type(ce->ce_mode), 1);
296+
else if (skip_prefix(format, "(objectsize)", &format))
297+
expand_objectsize(&sb, &ce->oid,
298+
object_type(ce->ce_mode), 0);
299+
else if (skip_prefix(format, "(stage)", &format))
300+
strbuf_addf(&sb, "%d", ce_stage(ce));
301+
else if (skip_prefix(format, "(eolinfo:index)", &format))
302+
strbuf_addstr(&sb, S_ISREG(ce->ce_mode) ?
303+
get_cached_convert_stats_ascii(repo->index,
304+
ce->name) : "");
305+
else if (skip_prefix(format, "(eolinfo:worktree)", &format))
306+
strbuf_addstr(&sb, !lstat(fullname, &st) &&
307+
S_ISREG(st.st_mode) ?
308+
get_wt_convert_stats_ascii(fullname) : "");
309+
else if (skip_prefix(format, "(eolattr)", &format))
310+
strbuf_addstr(&sb, get_convert_attr_ascii(repo->index,
311+
fullname));
312+
else if (skip_prefix(format, "(path)", &format))
313+
write_name_to_buf(&sb, fullname);
314+
else
315+
die(_("bad ls-files format: %%%.*s"),
316+
(int)(end - format + 1), format);
317+
}
335318
strbuf_addch(&sb, line_terminator);
336319
fwrite(sb.buf, sb.len, 1, stdout);
337320
strbuf_release(&sb);

builtin/ls-tree.c

Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -55,63 +55,6 @@ struct ls_tree_options {
5555
const char *format;
5656
};
5757

58-
struct show_tree_data {
59-
struct ls_tree_options *options;
60-
unsigned mode;
61-
enum object_type type;
62-
const struct object_id *oid;
63-
const char *pathname;
64-
struct strbuf *base;
65-
};
66-
67-
static size_t expand_show_tree(struct strbuf *sb, const char *start,
68-
void *context)
69-
{
70-
struct show_tree_data *data = context;
71-
struct ls_tree_options *options = data->options;
72-
const char *end;
73-
const char *p;
74-
unsigned int errlen;
75-
size_t len = strbuf_expand_literal_cb(sb, start, NULL);
76-
77-
if (len)
78-
return len;
79-
if (*start != '(')
80-
die(_("bad ls-tree format: element '%s' does not start with '('"), start);
81-
82-
end = strchr(start + 1, ')');
83-
if (!end)
84-
die(_("bad ls-tree format: element '%s' does not end in ')'"), start);
85-
86-
len = end - start + 1;
87-
if (skip_prefix(start, "(objectmode)", &p)) {
88-
strbuf_addf(sb, "%06o", data->mode);
89-
} else if (skip_prefix(start, "(objecttype)", &p)) {
90-
strbuf_addstr(sb, type_name(data->type));
91-
} else if (skip_prefix(start, "(objectsize:padded)", &p)) {
92-
expand_objectsize(sb, data->oid, data->type, 1);
93-
} else if (skip_prefix(start, "(objectsize)", &p)) {
94-
expand_objectsize(sb, data->oid, data->type, 0);
95-
} else if (skip_prefix(start, "(objectname)", &p)) {
96-
strbuf_add_unique_abbrev(sb, data->oid, options->abbrev);
97-
} else if (skip_prefix(start, "(path)", &p)) {
98-
const char *name = data->base->buf;
99-
const char *prefix = options->chomp_prefix ? options->ls_tree_prefix : NULL;
100-
struct strbuf sbuf = STRBUF_INIT;
101-
size_t baselen = data->base->len;
102-
103-
strbuf_addstr(data->base, data->pathname);
104-
name = relative_path(data->base->buf, prefix, &sbuf);
105-
quote_c_style(name, sb, NULL, 0);
106-
strbuf_setlen(data->base, baselen);
107-
strbuf_release(&sbuf);
108-
} else {
109-
errlen = (unsigned long)len;
110-
die(_("bad ls-tree format: %%%.*s"), errlen, start);
111-
}
112-
return len;
113-
}
114-
11558
static int show_recursive(struct ls_tree_options *options, const char *base,
11659
size_t baselen, const char *pathname)
11760
{
@@ -150,14 +93,7 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
15093
int recurse = 0;
15194
struct strbuf sb = STRBUF_INIT;
15295
enum object_type type = object_type(mode);
153-
struct show_tree_data cb_data = {
154-
.options = options,
155-
.mode = mode,
156-
.type = type,
157-
.oid = oid,
158-
.pathname = pathname,
159-
.base = base,
160-
};
96+
const char *format = options->format;
16197

16298
if (type == OBJ_TREE && show_recursive(options, base->buf, base->len, pathname))
16399
recurse = READ_TREE_RECURSIVE;
@@ -166,7 +102,46 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
166102
if (type == OBJ_BLOB && (options->ls_options & LS_TREE_ONLY))
167103
return 0;
168104

169-
strbuf_expand(&sb, options->format, expand_show_tree, &cb_data);
105+
while (strbuf_expand_step(&sb, &format)) {
106+
const char *end;
107+
size_t len;
108+
109+
if (skip_prefix(format, "%", &format))
110+
strbuf_addch(&sb, '%');
111+
else if ((len = strbuf_expand_literal(&sb, format)))
112+
format += len;
113+
else if (*format != '(')
114+
die(_("bad ls-tree format: element '%s' "
115+
"does not start with '('"), format);
116+
else if (!(end = strchr(format + 1, ')')))
117+
die(_("bad ls-tree format: element '%s' "
118+
"does not end in ')'"), format);
119+
else if (skip_prefix(format, "(objectmode)", &format))
120+
strbuf_addf(&sb, "%06o", mode);
121+
else if (skip_prefix(format, "(objecttype)", &format))
122+
strbuf_addstr(&sb, type_name(type));
123+
else if (skip_prefix(format, "(objectsize:padded)", &format))
124+
expand_objectsize(&sb, oid, type, 1);
125+
else if (skip_prefix(format, "(objectsize)", &format))
126+
expand_objectsize(&sb, oid, type, 0);
127+
else if (skip_prefix(format, "(objectname)", &format))
128+
strbuf_add_unique_abbrev(&sb, oid, options->abbrev);
129+
else if (skip_prefix(format, "(path)", &format)) {
130+
const char *name;
131+
const char *prefix = options->chomp_prefix ?
132+
options->ls_tree_prefix : NULL;
133+
struct strbuf sbuf = STRBUF_INIT;
134+
size_t baselen = base->len;
135+
136+
strbuf_addstr(base, pathname);
137+
name = relative_path(base->buf, prefix, &sbuf);
138+
quote_c_style(name, &sb, NULL, 0);
139+
strbuf_setlen(base, baselen);
140+
strbuf_release(&sbuf);
141+
} else
142+
die(_("bad ls-tree format: %%%.*s"),
143+
(int)(end - format + 1), format);
144+
}
170145
strbuf_addch(&sb, options->null_termination ? '\0' : '\n');
171146
fwrite(sb.buf, sb.len, 1, stdout);
172147
strbuf_release(&sb);

convert.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -634,23 +634,21 @@ static int filter_buffer_or_fd(int in UNUSED, int out, void *data)
634634
*/
635635
struct child_process child_process = CHILD_PROCESS_INIT;
636636
struct filter_params *params = (struct filter_params *)data;
637+
const char *format = params->cmd;
637638
int write_err, status;
638639

639640
/* apply % substitution to cmd */
640641
struct strbuf cmd = STRBUF_INIT;
641-
struct strbuf path = STRBUF_INIT;
642-
struct strbuf_expand_dict_entry dict[] = {
643-
{ "f", NULL, },
644-
{ NULL, NULL, },
645-
};
646-
647-
/* quote the path to preserve spaces, etc. */
648-
sq_quote_buf(&path, params->path);
649-
dict[0].value = path.buf;
650642

651-
/* expand all %f with the quoted path */
652-
strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict);
653-
strbuf_release(&path);
643+
/* expand all %f with the quoted path; quote to preserve space, etc. */
644+
while (strbuf_expand_step(&cmd, &format)) {
645+
if (skip_prefix(format, "%", &format))
646+
strbuf_addch(&cmd, '%');
647+
else if (skip_prefix(format, "f", &format))
648+
sq_quote_buf(&cmd, params->path);
649+
else
650+
strbuf_addch(&cmd, '%');
651+
}
654652

655653
strvec_push(&child_process.args, cmd.buf);
656654
child_process.use_shell = 1;

0 commit comments

Comments
 (0)