Skip to content

Commit 39dbd49

Browse files
rscharfegitster
authored andcommitted
replace strbuf_expand_dict_cb() with strbuf_expand_step()
Avoid the overhead of setting up a dictionary and passing it via strbuf_expand() to strbuf_expand_dict_cb() by using strbuf_expand_step() in a loop instead. It requires explicit handling of %% and unrecognized placeholders, but is more direct and simpler overall, and expands only on demand. Signed-off-by: René Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 44ccb33 commit 39dbd49

File tree

4 files changed

+28
-56
lines changed

4 files changed

+28
-56
lines changed

convert.c

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

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

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

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

ll-merge.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,24 +192,15 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
192192
const struct ll_merge_options *opts,
193193
int marker_size)
194194
{
195-
char temp[4][50];
195+
char temp[3][50];
196196
struct strbuf cmd = STRBUF_INIT;
197-
struct strbuf_expand_dict_entry dict[6];
198-
struct strbuf path_sq = STRBUF_INIT;
197+
const char *format = fn->cmdline;
199198
struct child_process child = CHILD_PROCESS_INIT;
200199
int status, fd, i;
201200
struct stat st;
202201
enum ll_merge_result ret;
203202
assert(opts);
204203

205-
sq_quote_buf(&path_sq, path);
206-
dict[0].placeholder = "O"; dict[0].value = temp[0];
207-
dict[1].placeholder = "A"; dict[1].value = temp[1];
208-
dict[2].placeholder = "B"; dict[2].value = temp[2];
209-
dict[3].placeholder = "L"; dict[3].value = temp[3];
210-
dict[4].placeholder = "P"; dict[4].value = path_sq.buf;
211-
dict[5].placeholder = NULL; dict[5].value = NULL;
212-
213204
if (!fn->cmdline)
214205
die("custom merge driver %s lacks command line.", fn->name);
215206

@@ -218,9 +209,23 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
218209
create_temp(orig, temp[0], sizeof(temp[0]));
219210
create_temp(src1, temp[1], sizeof(temp[1]));
220211
create_temp(src2, temp[2], sizeof(temp[2]));
221-
xsnprintf(temp[3], sizeof(temp[3]), "%d", marker_size);
222212

223-
strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);
213+
while (strbuf_expand_step(&cmd, &format)) {
214+
if (skip_prefix(format, "%", &format))
215+
strbuf_addch(&cmd, '%');
216+
else if (skip_prefix(format, "O", &format))
217+
strbuf_addstr(&cmd, temp[0]);
218+
else if (skip_prefix(format, "A", &format))
219+
strbuf_addstr(&cmd, temp[1]);
220+
else if (skip_prefix(format, "B", &format))
221+
strbuf_addstr(&cmd, temp[2]);
222+
else if (skip_prefix(format, "L", &format))
223+
strbuf_addf(&cmd, "%d", marker_size);
224+
else if (skip_prefix(format, "P", &format))
225+
sq_quote_buf(&cmd, path);
226+
else
227+
strbuf_addch(&cmd, '%');
228+
}
224229

225230
child.use_shell = 1;
226231
strvec_push(&child.args, cmd.buf);
@@ -242,7 +247,6 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
242247
for (i = 0; i < 3; i++)
243248
unlink_or_warn(temp[i]);
244249
strbuf_release(&cmd);
245-
strbuf_release(&path_sq);
246250
ret = (status > 0) ? LL_MERGE_CONFLICT : status;
247251
return ret;
248252
}

strbuf.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -468,22 +468,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb,
468468
return 0;
469469
}
470470

471-
size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder,
472-
void *context)
473-
{
474-
struct strbuf_expand_dict_entry *e = context;
475-
size_t len;
476-
477-
for (; e->placeholder && (len = strlen(e->placeholder)); e++) {
478-
if (!strncmp(placeholder, e->placeholder, len)) {
479-
if (e->value)
480-
strbuf_addstr(sb, e->value);
481-
return len;
482-
}
483-
}
484-
return 0;
485-
}
486-
487471
void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src)
488472
{
489473
size_t i, len = src->len;

strbuf.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -357,20 +357,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb,
357357
const char *placeholder,
358358
void *context);
359359

360-
/**
361-
* Used as callback for `strbuf_expand()`, expects an array of
362-
* struct strbuf_expand_dict_entry as context, i.e. pairs of
363-
* placeholder and replacement string. The array needs to be
364-
* terminated by an entry with placeholder set to NULL.
365-
*/
366-
struct strbuf_expand_dict_entry {
367-
const char *placeholder;
368-
const char *value;
369-
};
370-
size_t strbuf_expand_dict_cb(struct strbuf *sb,
371-
const char *placeholder,
372-
void *context);
373-
374360
/**
375361
* If the string pointed to by `formatp` contains a percent sign ("%"),
376362
* advance it to point to the character following the next one and

0 commit comments

Comments
 (0)