shell_escape: rename; refactor

- rename to shell_xescape_xquote
- move to os/shell.c
- disallow NULL argument
- eliminate casts, nesting
- test: empty shellxquote/shellxescape
This commit is contained in:
Justin M. Keyes
2016-09-11 01:50:58 +02:00
parent 0991041ae7
commit 395ef5642e
2 changed files with 56 additions and 65 deletions

View File

@@ -37,51 +37,6 @@ typedef struct {
# include "os/shell.c.generated.h"
#endif
/// Process command string with 'shellxescape' (p_sxe) and 'shellxquote'
/// (p_sxq)
///
/// @param cmd Command string
/// @return NULL if `cmd` is NULL. Otherwise, a newly allocated command string.
/// It must be freed with `xfree` when no longer needed.
static char *shell_escape(const char *cmd)
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
char *ncmd;
if (cmd == NULL) {
ncmd = NULL;
} else if (*p_sxq == NUL) {
ncmd = xstrdup(cmd);
} else {
const char *ecmd;
size_t ncmd_size;
if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) {
ecmd = (char *)vim_strsave_escaped_ext((char_u *)cmd, p_sxe, '^', false);
} else {
ecmd = cmd;
}
ncmd_size = strlen(ecmd) + STRLEN(p_sxq) * 2 + 1;
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 != (const char *)cmd) {
xfree((void *)ecmd);
}
}
return ncmd;
}
/// Builds the argument vector for running the user-configured 'shell' (p_sh)
/// with an optional command prefixed by 'shellcmdflag' (p_shcf).
///
@@ -99,13 +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++] = shell_escape(cmd); // Process command string with
// 'shellxescape' and 'shellxquote'
i += tokenize(p_shcf, rv + i); // Split 'shellcmdflag'
rv[i++] = shell_xescape_xquote(cmd); // Copy (and escape) `cmd`.
}
rv[i] = NULL;
@@ -594,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;
}