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 <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
44ccb337f1
commit
39dbd49b41
22
convert.c
22
convert.c
@ -633,23 +633,21 @@ static int filter_buffer_or_fd(int in UNUSED, int out, void *data)
|
|||||||
*/
|
*/
|
||||||
struct child_process child_process = CHILD_PROCESS_INIT;
|
struct child_process child_process = CHILD_PROCESS_INIT;
|
||||||
struct filter_params *params = (struct filter_params *)data;
|
struct filter_params *params = (struct filter_params *)data;
|
||||||
|
const char *format = params->cmd;
|
||||||
int write_err, status;
|
int write_err, status;
|
||||||
|
|
||||||
/* apply % substitution to cmd */
|
/* apply % substitution to cmd */
|
||||||
struct strbuf cmd = STRBUF_INIT;
|
struct strbuf cmd = STRBUF_INIT;
|
||||||
struct strbuf path = STRBUF_INIT;
|
|
||||||
struct strbuf_expand_dict_entry dict[] = {
|
|
||||||
{ "f", NULL, },
|
|
||||||
{ NULL, NULL, },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* quote the path to preserve spaces, etc. */
|
/* expand all %f with the quoted path; quote to preserve space, etc. */
|
||||||
sq_quote_buf(&path, params->path);
|
while (strbuf_expand_step(&cmd, &format)) {
|
||||||
dict[0].value = path.buf;
|
if (skip_prefix(format, "%", &format))
|
||||||
|
strbuf_addch(&cmd, '%');
|
||||||
/* expand all %f with the quoted path */
|
else if (skip_prefix(format, "f", &format))
|
||||||
strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict);
|
sq_quote_buf(&cmd, params->path);
|
||||||
strbuf_release(&path);
|
else
|
||||||
|
strbuf_addch(&cmd, '%');
|
||||||
|
}
|
||||||
|
|
||||||
strvec_push(&child_process.args, cmd.buf);
|
strvec_push(&child_process.args, cmd.buf);
|
||||||
child_process.use_shell = 1;
|
child_process.use_shell = 1;
|
||||||
|
32
ll-merge.c
32
ll-merge.c
@ -192,24 +192,15 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
|
|||||||
const struct ll_merge_options *opts,
|
const struct ll_merge_options *opts,
|
||||||
int marker_size)
|
int marker_size)
|
||||||
{
|
{
|
||||||
char temp[4][50];
|
char temp[3][50];
|
||||||
struct strbuf cmd = STRBUF_INIT;
|
struct strbuf cmd = STRBUF_INIT;
|
||||||
struct strbuf_expand_dict_entry dict[6];
|
const char *format = fn->cmdline;
|
||||||
struct strbuf path_sq = STRBUF_INIT;
|
|
||||||
struct child_process child = CHILD_PROCESS_INIT;
|
struct child_process child = CHILD_PROCESS_INIT;
|
||||||
int status, fd, i;
|
int status, fd, i;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
enum ll_merge_result ret;
|
enum ll_merge_result ret;
|
||||||
assert(opts);
|
assert(opts);
|
||||||
|
|
||||||
sq_quote_buf(&path_sq, path);
|
|
||||||
dict[0].placeholder = "O"; dict[0].value = temp[0];
|
|
||||||
dict[1].placeholder = "A"; dict[1].value = temp[1];
|
|
||||||
dict[2].placeholder = "B"; dict[2].value = temp[2];
|
|
||||||
dict[3].placeholder = "L"; dict[3].value = temp[3];
|
|
||||||
dict[4].placeholder = "P"; dict[4].value = path_sq.buf;
|
|
||||||
dict[5].placeholder = NULL; dict[5].value = NULL;
|
|
||||||
|
|
||||||
if (!fn->cmdline)
|
if (!fn->cmdline)
|
||||||
die("custom merge driver %s lacks command line.", fn->name);
|
die("custom merge driver %s lacks command line.", fn->name);
|
||||||
|
|
||||||
@ -218,9 +209,23 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
|
|||||||
create_temp(orig, temp[0], sizeof(temp[0]));
|
create_temp(orig, temp[0], sizeof(temp[0]));
|
||||||
create_temp(src1, temp[1], sizeof(temp[1]));
|
create_temp(src1, temp[1], sizeof(temp[1]));
|
||||||
create_temp(src2, temp[2], sizeof(temp[2]));
|
create_temp(src2, temp[2], sizeof(temp[2]));
|
||||||
xsnprintf(temp[3], sizeof(temp[3]), "%d", marker_size);
|
|
||||||
|
|
||||||
strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);
|
while (strbuf_expand_step(&cmd, &format)) {
|
||||||
|
if (skip_prefix(format, "%", &format))
|
||||||
|
strbuf_addch(&cmd, '%');
|
||||||
|
else if (skip_prefix(format, "O", &format))
|
||||||
|
strbuf_addstr(&cmd, temp[0]);
|
||||||
|
else if (skip_prefix(format, "A", &format))
|
||||||
|
strbuf_addstr(&cmd, temp[1]);
|
||||||
|
else if (skip_prefix(format, "B", &format))
|
||||||
|
strbuf_addstr(&cmd, temp[2]);
|
||||||
|
else if (skip_prefix(format, "L", &format))
|
||||||
|
strbuf_addf(&cmd, "%d", marker_size);
|
||||||
|
else if (skip_prefix(format, "P", &format))
|
||||||
|
sq_quote_buf(&cmd, path);
|
||||||
|
else
|
||||||
|
strbuf_addch(&cmd, '%');
|
||||||
|
}
|
||||||
|
|
||||||
child.use_shell = 1;
|
child.use_shell = 1;
|
||||||
strvec_push(&child.args, cmd.buf);
|
strvec_push(&child.args, cmd.buf);
|
||||||
@ -242,7 +247,6 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
|
|||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
unlink_or_warn(temp[i]);
|
unlink_or_warn(temp[i]);
|
||||||
strbuf_release(&cmd);
|
strbuf_release(&cmd);
|
||||||
strbuf_release(&path_sq);
|
|
||||||
ret = (status > 0) ? LL_MERGE_CONFLICT : status;
|
ret = (status > 0) ? LL_MERGE_CONFLICT : status;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
16
strbuf.c
16
strbuf.c
@ -468,22 +468,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder,
|
|
||||||
void *context)
|
|
||||||
{
|
|
||||||
struct strbuf_expand_dict_entry *e = context;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
for (; e->placeholder && (len = strlen(e->placeholder)); e++) {
|
|
||||||
if (!strncmp(placeholder, e->placeholder, len)) {
|
|
||||||
if (e->value)
|
|
||||||
strbuf_addstr(sb, e->value);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src)
|
void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src)
|
||||||
{
|
{
|
||||||
size_t i, len = src->len;
|
size_t i, len = src->len;
|
||||||
|
14
strbuf.h
14
strbuf.h
@ -357,20 +357,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb,
|
|||||||
const char *placeholder,
|
const char *placeholder,
|
||||||
void *context);
|
void *context);
|
||||||
|
|
||||||
/**
|
|
||||||
* Used as callback for `strbuf_expand()`, expects an array of
|
|
||||||
* struct strbuf_expand_dict_entry as context, i.e. pairs of
|
|
||||||
* placeholder and replacement string. The array needs to be
|
|
||||||
* terminated by an entry with placeholder set to NULL.
|
|
||||||
*/
|
|
||||||
struct strbuf_expand_dict_entry {
|
|
||||||
const char *placeholder;
|
|
||||||
const char *value;
|
|
||||||
};
|
|
||||||
size_t strbuf_expand_dict_cb(struct strbuf *sb,
|
|
||||||
const char *placeholder,
|
|
||||||
void *context);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the string pointed to by `formatp` contains a percent sign ("%"),
|
* If the string pointed to by `formatp` contains a percent sign ("%"),
|
||||||
* advance it to point to the character following the next one and
|
* advance it to point to the character following the next one and
|
||||||
|
Reference in New Issue
Block a user