diff options
author | Bram Moolenaar <Bram@vim.org> | 2014-04-05 18:55:46 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2014-04-05 18:55:46 +0200 |
commit | 57ebe6e2f94edad6adc43246d98919e728095211 (patch) | |
tree | 7dc2718ae060133f59a57c82835e359defa05dfc | |
parent | 4ed89cdf41cf3d509fd30e6f7c577a7c090679a9 (diff) | |
download | vim-57ebe6e2f94edad6adc43246d98919e728095211.zip |
updated for version 7.4.247
Problem: When passing input to system() there is no way to keep NUL and
NL characters separate.
Solution: Optionally use a list for the system() input. (ZyX)
-rw-r--r-- | runtime/doc/eval.txt | 15 | ||||
-rw-r--r-- | src/eval.c | 96 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 73 insertions, 40 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 3e839fb3e..a4bb1f40e 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -5964,10 +5964,17 @@ synstack({lnum}, {col}) *synstack()* system({expr} [, {input}]) *system()* *E677* Get the output of the shell command {expr}. - When {input} is given, this string is written to a file and - passed as stdin to the command. The string is written as-is, - you need to take care of using the correct line separators - yourself. Pipes are not used. + + When {input} is given and is a string this string is written + to a file and passed as stdin to the command. The string is + written as-is, you need to take care of using the correct line + separators yourself. + If {input} is given and is a |List| it is written to the file + in a way |writefile()| does with {binary} set to "b" (i.e. + with a newline between each list item with newlines inside + list items converted to NULs). + Pipes are not used. + Note: Use |shellescape()| or |::S| with |expand()| or |fnamemodify()| to escape special characters in a command argument. Newlines in {expr} may cause the command to fail. diff --git a/src/eval.c b/src/eval.c index 3d5670948..df8c09475 100644 --- a/src/eval.c +++ b/src/eval.c @@ -836,6 +836,7 @@ static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); +static int write_list __ARGS((FILE *fd, list_T *list, int binary)); #ifdef EBCDIC @@ -18267,14 +18268,22 @@ f_system(argvars, rettv) EMSG2(_(e_notopen), infile); goto done; } - p = get_tv_string_buf_chk(&argvars[1], buf); - if (p == NULL) + if (argvars[1].v_type == VAR_LIST) { - fclose(fd); - goto done; /* type error; errmsg already given */ + if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL) + err = TRUE; + } + else + { + p = get_tv_string_buf_chk(&argvars[1], buf); + if (p == NULL) + { + fclose(fd); + goto done; /* type error; errmsg already given */ + } + if (fwrite(p, STRLEN(p), 1, fd) != 1) + err = TRUE; } - if (fwrite(p, STRLEN(p), 1, fd) != 1) - err = TRUE; if (fclose(fd) != 0) err = TRUE; if (err) @@ -19173,6 +19182,49 @@ f_winwidth(argvars, rettv) } /* + * Write list of strings to file + */ + static int +write_list(fd, list, binary) + FILE *fd; + list_T *list; + int binary; +{ + listitem_T *li; + int c; + int ret = OK; + char_u *s; + + for (li = list->lv_first; li != NULL; li = li->li_next) + { + for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) + { + if (*s == '\n') + c = putc(NUL, fd); + else + c = putc(*s, fd); + if (c == EOF) + { + ret = FAIL; + break; + } + } + if (!binary || li->li_next != NULL) + if (putc('\n', fd) == EOF) + { + ret = FAIL; + break; + } + if (ret == FAIL) + { + EMSG(_(e_write)); + break; + } + } + return ret; +} + +/* * "writefile()" function */ static void @@ -19183,10 +19235,7 @@ f_writefile(argvars, rettv) int binary = FALSE; char_u *fname; FILE *fd; - listitem_T *li; - char_u *s; int ret = 0; - int c; if (check_restricted() || check_secure()) return; @@ -19213,33 +19262,8 @@ f_writefile(argvars, rettv) } else { - for (li = argvars[0].vval.v_list->lv_first; li != NULL; - li = li->li_next) - { - for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) - { - if (*s == '\n') - c = putc(NUL, fd); - else - c = putc(*s, fd); - if (c == EOF) - { - ret = -1; - break; - } - } - if (!binary || li->li_next != NULL) - if (putc('\n', fd) == EOF) - { - ret = -1; - break; - } - if (ret < 0) - { - EMSG(_(e_write)); - break; - } - } + if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL) + ret = -1; fclose(fd); } diff --git a/src/version.c b/src/version.c index 420f4e3c3..85596c8ab 100644 --- a/src/version.c +++ b/src/version.c @@ -735,6 +735,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 247, +/**/ 246, /**/ 245, |