aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2022-08-01 12:02:53 +0100
committerGitHub <noreply@github.com>2022-08-01 12:02:53 +0100
commitbcb4186cf67b22dab238248a809f6c3f09a5424d (patch)
tree139ad47c10deda09a68d87f7d93940a21891c023
parent8952def50afa8308e044c0100e6d4fa367d0a9c2 (diff)
downloadrneovim-bcb4186cf67b22dab238248a809f6c3f09a5424d.tar.gz
rneovim-bcb4186cf67b22dab238248a809f6c3f09a5424d.tar.bz2
rneovim-bcb4186cf67b22dab238248a809f6c3f09a5424d.zip
refactor: replace_makeprg (#19570)
-rw-r--r--src/nvim/ex_docmd.c72
-rw-r--r--src/nvim/strings.c42
2 files changed, 62 insertions, 52 deletions
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 "<makeprg> <arg>" 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;
+}