From bcb4186cf67b22dab238248a809f6c3f09a5424d Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 1 Aug 2022 12:02:53 +0100 Subject: refactor: replace_makeprg (#19570) --- src/nvim/ex_docmd.c | 72 +++++++++++++++-------------------------------------- src/nvim/strings.c | 42 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3127c7e922..a7d91a47d7 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4738,71 +4738,39 @@ static char *skip_grep_pat(exarg_T *eap) /// For the ":make" and ":grep" commands insert the 'makeprg'/'grepprg' option /// in the command line, so that things like % get expanded. -char *replace_makeprg(exarg_T *eap, char *p, char **cmdlinep) +char *replace_makeprg(exarg_T *eap, char *arg, char **cmdlinep) { - char *new_cmdline; - char *program; - char *pos; - char *ptr; - int len; - size_t i; + bool isgrep = eap->cmdidx == CMD_grep + || eap->cmdidx == CMD_lgrep + || eap->cmdidx == CMD_grepadd + || eap->cmdidx == CMD_lgrepadd; - /* - * Don't do it when ":vimgrep" is used for ":grep". - */ - if ((eap->cmdidx == CMD_make || eap->cmdidx == CMD_lmake - || eap->cmdidx == CMD_grep || eap->cmdidx == CMD_lgrep - || eap->cmdidx == CMD_grepadd - || eap->cmdidx == CMD_lgrepadd) + // Don't do it when ":vimgrep" is used for ":grep". + if ((eap->cmdidx == CMD_make || eap->cmdidx == CMD_lmake || isgrep) && !grep_internal(eap->cmdidx)) { - if (eap->cmdidx == CMD_grep || eap->cmdidx == CMD_lgrep - || eap->cmdidx == CMD_grepadd || eap->cmdidx == CMD_lgrepadd) { - if (*curbuf->b_p_gp == NUL) { - program = (char *)p_gp; - } else { - program = (char *)curbuf->b_p_gp; - } - } else { - if (*curbuf->b_p_mp == NUL) { - program = (char *)p_mp; - } else { - program = (char *)curbuf->b_p_mp; - } - } + const char *program = isgrep ? (*curbuf->b_p_gp == NUL ? (char *)p_gp : (char *)curbuf->b_p_gp) + : (*curbuf->b_p_mp == NUL ? (char *)p_mp : (char *)curbuf->b_p_mp); - p = skipwhite(p); + arg = skipwhite(arg); - if ((pos = strstr(program, "$*")) != NULL) { - // replace $* by given arguments - i = 1; - while ((pos = strstr(pos + 2, "$*")) != NULL) { - i++; - } - len = (int)STRLEN(p); - new_cmdline = xmalloc(STRLEN(program) + i * (size_t)(len - 2) + 1); - ptr = new_cmdline; - while ((pos = strstr(program, "$*")) != NULL) { - i = (size_t)(pos - program); - memcpy(ptr, program, i); - STRCPY(ptr += i, p); - ptr += len; - program = pos + 2; - } - STRCPY(ptr, program); - } else { - new_cmdline = xmalloc(STRLEN(program) + STRLEN(p) + 2); + char *new_cmdline; + // Replace $* by given arguments + if ((new_cmdline = strrep(program, "$*", arg)) == NULL) { + // No $* in arg, build " " instead + new_cmdline = xmalloc(STRLEN(program) + STRLEN(arg) + 2); STRCPY(new_cmdline, program); STRCAT(new_cmdline, " "); - STRCAT(new_cmdline, p); + STRCAT(new_cmdline, arg); } - msg_make((char_u *)p); + + msg_make((char_u *)arg); // 'eap->cmd' is not set here, because it is not used at CMD_make xfree(*cmdlinep); *cmdlinep = new_cmdline; - p = new_cmdline; + arg = new_cmdline; } - return p; + return arg; } /// Expand file name in Ex command argument. diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 867fa73419..22effaade0 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1528,3 +1528,45 @@ char_u *reverse_text(char_u *s) return rev; } + +/// Replace all occurrences of "what" with "rep" in "src". If no replacement happens then NULL is +/// returned otherwise return a newly allocated string. +/// +/// @param[in] src Source text +/// @param[in] what Substring to replace +/// @param[in] rep Substring to replace with +/// +/// @return [allocated] Copy of the string. +char *strrep(const char *src, const char *what, const char *rep) +{ + char *pos = (char *)src; + size_t whatlen = STRLEN(what); + + // Count occurrences + size_t count = 0; + while ((pos = strstr(pos, what)) != NULL) { + count++; + pos += whatlen; + } + + if (count == 0) { + return NULL; + } + + size_t replen = STRLEN(rep); + char *ret = xmalloc(STRLEN(src) + count * (replen - whatlen) + 1); + char *ptr = ret; + while ((pos = strstr(src, what)) != NULL) { + size_t idx = (size_t)(pos - src); + memcpy(ptr, src, idx); + ptr += idx; + STRCPY(ptr, rep); + ptr += replen; + src = pos + whatlen; + } + + // Copy remaining + STRCPY(ptr, src); + + return ret; +} -- cgit