diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/misc2.c | 24 | ||||
| -rw-r--r-- | src/nvim/os/shell.c | 42 | 
2 files changed, 40 insertions, 26 deletions
| diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c index 368f83cfb5..8b4d8c7c3e 100644 --- a/src/nvim/misc2.c +++ b/src/nvim/misc2.c @@ -281,7 +281,6 @@ int default_fileformat(void)  // Call shell. Calls os_call_shell, with 'shellxquote' added.  int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)  { -  char_u      *ncmd;    int retval;    proftime_T wait_time; @@ -303,28 +302,7 @@ int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)      /* The external command may update a tags file, clear cached tags. */      tag_freematch(); -    if (cmd == NULL || *p_sxq == NUL) -      retval = os_call_shell(cmd, opts, extra_shell_arg); -    else { -      char_u *ecmd = cmd; - -      if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) { -        ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE); -      } -      ncmd = xmalloc(STRLEN(ecmd) + STRLEN(p_sxq) * 2 + 1); -      STRCPY(ncmd, p_sxq); -      STRCAT(ncmd, ecmd); -      /* When 'shellxquote' is ( append ). -       * When 'shellxquote' is "( append )". */ -      STRCAT(ncmd, STRCMP(p_sxq, "(") == 0 ? (char_u *)")" -          : STRCMP(p_sxq, "\"(") == 0 ? (char_u *)")\"" -          : p_sxq); -      retval = os_call_shell(ncmd, opts, extra_shell_arg); -      xfree(ncmd); - -      if (ecmd != cmd) -        xfree(ecmd); -    } +    retval = os_call_shell(cmd, opts, extra_shell_arg);    }    set_vim_var_nr(VV_SHELL_ERROR, (varnumber_T) retval); diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index ba52b9f661..99ae3af221 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -54,12 +54,12 @@ char **shell_build_argv(const char *cmd, const char *extra_args)    size_t i = tokenize(p_sh, rv);    if (extra_args) { -    rv[i++] = xstrdup(extra_args);   // Push a copy of `extra_args` +    rv[i++] = xstrdup(extra_args);        // Push a copy of `extra_args`    }    if (cmd) { -    i += tokenize(p_shcf, rv + i);   // Split 'shellcmdflag' -    rv[i++] = xstrdup(cmd);          // Push a copy of the command. +    i += tokenize(p_shcf, rv + i);        // Split 'shellcmdflag' +    rv[i++] = shell_xescape_xquote(cmd);  // Copy (and escape) `cmd`.    }    rv[i] = NULL; @@ -548,3 +548,39 @@ static void shell_write_cb(Stream *stream, void *data, int status)  {    stream_close(stream, NULL, NULL);  } + +/// Applies 'shellxescape' (p_sxe) and 'shellxquote' (p_sxq) to a command. +/// +/// @param cmd Command string +/// @return    Escaped/quoted command string (allocated). +static char *shell_xescape_xquote(const char *cmd) +  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT +{ +  if (*p_sxq == NUL) { +    return xstrdup(cmd); +  } + +  const char *ecmd = cmd; +  if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) { +    ecmd = (char *)vim_strsave_escaped_ext((char_u *)cmd, p_sxe, '^', false); +  } +  size_t ncmd_size = strlen(ecmd) + STRLEN(p_sxq) * 2 + 1; +  char *ncmd = xmalloc(ncmd_size); + +  // When 'shellxquote' is ( append ). +  // When 'shellxquote' is "( append )". +  if (STRCMP(p_sxq, "(") == 0) { +    vim_snprintf(ncmd, ncmd_size, "(%s)", ecmd); +  } else if (STRCMP(p_sxq, "\"(") == 0) { +    vim_snprintf(ncmd, ncmd_size, "\"(%s)\"", ecmd); +  } else { +    vim_snprintf(ncmd, ncmd_size, "%s%s%s", p_sxq, ecmd, p_sxq); +  } + +  if (ecmd != cmd) { +    xfree((void *)ecmd); +  } + +  return ncmd; +} + | 
