]> git.ipfire.org Git - thirdparty/git.git/commitdiff
replace strbuf_expand_dict_cb() with strbuf_expand_step()
authorRené Scharfe <l.s.r@web.de>
Sat, 17 Jun 2023 20:42:26 +0000 (22:42 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sun, 18 Jun 2023 19:55:30 +0000 (12:55 -0700)
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>
convert.c
ll-merge.c
strbuf.c
strbuf.h

index 9ee79fe4699ef1c4cc1d070f82153aaf8b17aa88..455d05cf6b30690b8b76bbe086d03b921fd59500 100644 (file)
--- a/convert.c
+++ b/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 filter_params *params = (struct filter_params *)data;
+       const char *format = params->cmd;
        int write_err, status;
 
        /* apply % substitution to cmd */
        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. */
-       sq_quote_buf(&path, params->path);
-       dict[0].value = path.buf;
 
-       /* expand all %f with the quoted path */
-       strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict);
-       strbuf_release(&path);
+       /* expand all %f with the quoted path; quote to preserve space, etc. */
+       while (strbuf_expand_step(&cmd, &format)) {
+               if (skip_prefix(format, "%", &format))
+                       strbuf_addch(&cmd, '%');
+               else if (skip_prefix(format, "f", &format))
+                       sq_quote_buf(&cmd, params->path);
+               else
+                       strbuf_addch(&cmd, '%');
+       }
 
        strvec_push(&child_process.args, cmd.buf);
        child_process.use_shell = 1;
index 07ec16e8e5bb59f091a1c41df123abce3cefe337..b307ad293c728b43bb598de65848b49977559fc4 100644 (file)
@@ -192,24 +192,15 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
                        const struct ll_merge_options *opts,
                        int marker_size)
 {
-       char temp[4][50];
+       char temp[3][50];
        struct strbuf cmd = STRBUF_INIT;
-       struct strbuf_expand_dict_entry dict[6];
-       struct strbuf path_sq = STRBUF_INIT;
+       const char *format = fn->cmdline;
        struct child_process child = CHILD_PROCESS_INIT;
        int status, fd, i;
        struct stat st;
        enum ll_merge_result ret;
        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)
                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(src1, temp[1], sizeof(temp[1]));
        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;
        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++)
                unlink_or_warn(temp[i]);
        strbuf_release(&cmd);
-       strbuf_release(&path_sq);
        ret = (status > 0) ? LL_MERGE_CONFLICT : status;
        return ret;
 }
index a90b597da10c6f1bce48d84d610e43db44e4807d..972366b41092552012b5d9558a27b55524cdcbd2 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -468,22 +468,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb,
        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)
 {
        size_t i, len = src->len;
index a189f12b84e6f427493cef675c66945b7532f6c5..e293117f0722678c1308b3684fc4f4fd00779e77 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -357,20 +357,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb,
                                const char *placeholder,
                                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 ("%"),
  * advance it to point to the character following the next one and