diff options
Diffstat (limited to 'src/os/shell.c')
-rw-r--r-- | src/os/shell.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/os/shell.c b/src/os/shell.c index cbedf72a9c..2f3f2f6095 100644 --- a/src/os/shell.c +++ b/src/os/shell.c @@ -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; +} |