Extract shell_build_argv from mch_call_shell

This commit is contained in:
Thiago de Arruda 2014-03-29 14:28:44 -03:00
parent c791922224
commit f496d619a9
3 changed files with 67 additions and 43 deletions

View File

@ -1,9 +1,12 @@
#include <string.h>
#include <stdbool.h>
#include "os/shell.h"
#include "types.h"
#include "vim.h"
#include "ascii.h"
#include "misc2.h"
#include "option_defs.h"
#include "charset.h"
@ -54,4 +57,60 @@ int shell_count_argc(char_u **ptr)
return rv;
}
char ** shell_build_argv(char_u **ptr, int argc);
char ** shell_build_argv(int argc, char_u *cmd,
char_u *extra_shell_arg, char_u **ptr, char_u **p_shcf_copy_ptr)
{
char **argv;
char_u *p_shcf_copy = *p_shcf_copy_ptr;
char_u *p = *ptr;
// Allocate argv memory
argv = (char **)alloc((unsigned)((argc + 4) * sizeof(char *)));
if (argv == NULL) // out of memory
return NULL;
// Build argv[]
argc = 0;
while (true) {
argv[argc] = (char *)p;
++argc;
shell_skip_word(&p);
if (*p == NUL)
break;
// Terminate the word
*p++ = NUL;
p = skipwhite(p);
}
if (cmd != NULL) {
char_u *s;
if (extra_shell_arg != NULL)
argv[argc++] = (char *)extra_shell_arg;
// Break 'shellcmdflag' into white separated parts. This doesn't
// handle quoted strings, they are very unlikely to appear.
p_shcf_copy = alloc((unsigned)STRLEN(p_shcf) + 1);
if (p_shcf_copy == NULL) {
// out of memory
free(argv);
return NULL;
}
s = p_shcf_copy;
p = p_shcf;
while (*p != NUL) {
argv[argc++] = (char *)s;
while (*p && *p != ' ' && *p != TAB)
*s++ = *p++;
*s++ = NUL;
p = skipwhite(p);
}
argv[argc++] = (char *)cmd;
}
argv[argc] = NULL;
*ptr = p;
*p_shcf_copy_ptr = p_shcf_copy;
return argv;
}

View File

@ -7,6 +7,8 @@
void shell_skip_word(char_u **ptr);
int shell_count_argc(char_u **ptr);
char ** shell_build_argv(int argc, char_u *cmd,
char_u *extra_shell_arg, char_u **ptr, char_u **p_shcf_copy_ptr);
#endif // NEOVIM_OS_SHELL_H

View File

@ -1721,51 +1721,14 @@ int mch_call_shell(char_u *cmd, int options, char_u *extra_shell_arg)
// Count the number of arguments for the shell
p = newcmd;
argc = shell_count_argc(&p);
// Allocate argv memory
argv = (char **)alloc((unsigned)((argc + 4) * sizeof(char *)));
if (argv == NULL) // out of memory
goto error;
// Build argv[]
p = newcmd;
argc = 0;
while (true) {
argv[argc] = (char *)p;
++argc;
shell_skip_word(&p);
if (*p == NUL)
break;
// Terminate the word
*p++ = NUL;
p = skipwhite(p);
argv = shell_build_argv(argc, cmd, extra_shell_arg, &p, &p_shcf_copy);
if (argv == NULL) {
goto error;
}
if (cmd != NULL) {
char_u *s;
if (extra_shell_arg != NULL)
argv[argc++] = (char *)extra_shell_arg;
/* Break 'shellcmdflag' into white separated parts. This doesn't
* handle quoted strings, they are very unlikely to appear. */
p_shcf_copy = alloc((unsigned)STRLEN(p_shcf) + 1);
if (p_shcf_copy == NULL) /* out of memory */
goto error;
s = p_shcf_copy;
p = p_shcf;
while (*p != NUL) {
argv[argc++] = (char *)s;
while (*p && *p != ' ' && *p != TAB)
*s++ = *p++;
*s++ = NUL;
p = skipwhite(p);
}
argv[argc++] = (char *)cmd;
}
argv[argc] = NULL;
/*
/*
* For the GUI, when writing the output into the buffer and when reading
* input from the buffer: Try using a pseudo-tty to get the stdin/stdout
* of the executed command into the Vim window. Or use a pipe.