Skip to content

Commit 6f1e2d5

Browse files
rscharfegitster
authored andcommitted
replace strbuf_expand() with strbuf_expand_step()
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 39dbd49 commit 6f1e2d5

File tree

7 files changed

+169
-272
lines changed

7 files changed

+169
-272
lines changed

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)
@@ -494,7 +494,7 @@ static void batch_object_write(const char *obj_name,
494494
if (!opt->format) {
495495
print_default_format(scratch, data);
496496
} else {
497-
strbuf_expand(scratch, opt->format, expand_format, data);
497+
expand_format(scratch, opt->format, data);
498498
strbuf_addch(scratch, '\n');
499499
}
500500

@@ -777,9 +777,8 @@ static int batch_objects(struct batch_options *opt)
777777
*/
778778
memset(&data, 0, sizeof(data));
779779
data.mark_query = 1;
780-
strbuf_expand(&output,
780+
expand_format(&output,
781781
opt->format ? opt->format : DEFAULT_FORMAT,
782-
expand_format,
783782
&data);
784783
data.mark_query = 0;
785784
strbuf_release(&output);

builtin/ls-files.c

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

323266
static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce,
324267
const char *format, const char *fullname) {
325-
struct show_index_data data = {
326-
.pathname = fullname,
327-
.istate = repo->index,
328-
.ce = ce,
329-
};
330268
struct strbuf sb = STRBUF_INIT;
331269

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

daemon.c

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -144,42 +144,6 @@ static void NORETURN daemon_die(const char *err, va_list params)
144144
exit(1);
145145
}
146146

147-
struct expand_path_context {
148-
const char *directory;
149-
struct hostinfo *hostinfo;
150-
};
151-
152-
static size_t expand_path(struct strbuf *sb, const char *placeholder, void *ctx)
153-
{
154-
struct expand_path_context *context = ctx;
155-
struct hostinfo *hi = context->hostinfo;
156-
157-
switch (placeholder[0]) {
158-
case 'H':
159-
strbuf_addbuf(sb, &hi->hostname);
160-
return 1;
161-
case 'C':
162-
if (placeholder[1] == 'H') {
163-
strbuf_addstr(sb, get_canon_hostname(hi));
164-
return 2;
165-
}
166-
break;
167-
case 'I':
168-
if (placeholder[1] == 'P') {
169-
strbuf_addstr(sb, get_ip_address(hi));
170-
return 2;
171-
}
172-
break;
173-
case 'P':
174-
strbuf_addbuf(sb, &hi->tcp_port);
175-
return 1;
176-
case 'D':
177-
strbuf_addstr(sb, context->directory);
178-
return 1;
179-
}
180-
return 0;
181-
}
182-
183147
static const char *path_ok(const char *directory, struct hostinfo *hi)
184148
{
185149
static char rpath[PATH_MAX];
@@ -223,19 +187,32 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
223187
}
224188
else if (interpolated_path && hi->saw_extended_args) {
225189
struct strbuf expanded_path = STRBUF_INIT;
226-
struct expand_path_context context;
227-
228-
context.directory = directory;
229-
context.hostinfo = hi;
190+
const char *format = interpolated_path;
230191

231192
if (*dir != '/') {
232193
/* Allow only absolute */
233194
logerror("'%s': Non-absolute path denied (interpolated-path active)", dir);
234195
return NULL;
235196
}
236197

237-
strbuf_expand(&expanded_path, interpolated_path,
238-
expand_path, &context);
198+
while (strbuf_expand_step(&expanded_path, &format)) {
199+
if (skip_prefix(format, "%", &format))
200+
strbuf_addch(&expanded_path, '%');
201+
else if (skip_prefix(format, "H", &format))
202+
strbuf_addbuf(&expanded_path, &hi->hostname);
203+
else if (skip_prefix(format, "CH", &format))
204+
strbuf_addstr(&expanded_path,
205+
get_canon_hostname(hi));
206+
else if (skip_prefix(format, "IP", &format))
207+
strbuf_addstr(&expanded_path,
208+
get_ip_address(hi));
209+
else if (skip_prefix(format, "P", &format))
210+
strbuf_addbuf(&expanded_path, &hi->tcp_port);
211+
else if (skip_prefix(format, "D", &format))
212+
strbuf_addstr(&expanded_path, directory);
213+
else
214+
strbuf_addch(&expanded_path, '%');
215+
}
239216

240217
rlen = strlcpy(interp_path, expanded_path.buf,
241218
sizeof(interp_path));

0 commit comments

Comments
 (0)