diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2016-09-11 03:27:35 +0200 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2016-09-11 03:27:35 +0200 |
commit | ca65514a241b239e656cb87f0912bd9ba2e18ad8 (patch) | |
tree | 104596d8b46c823969085c4ebf8a39dd12982646 /src/nvim/os/shell.c | |
parent | 8dc6c1a7ff97700a0622497245f2d5d257e1dfdb (diff) | |
parent | 395ef5642e6e61d8f59d1ef67dd7d203b9bb72e6 (diff) | |
download | rneovim-ca65514a241b239e656cb87f0912bd9ba2e18ad8.tar.gz rneovim-ca65514a241b239e656cb87f0912bd9ba2e18ad8.tar.bz2 rneovim-ca65514a241b239e656cb87f0912bd9ba2e18ad8.zip |
Merge #2789 'system(): Respect shellxescape, shellxquote'
Diffstat (limited to 'src/nvim/os/shell.c')
-rw-r--r-- | src/nvim/os/shell.c | 42 |
1 files changed, 39 insertions, 3 deletions
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; +} + |