aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Prager <splinterofchaos@gmail.com>2014-09-04 23:44:24 -0400
committerScott Prager <splinterofchaos@gmail.com>2014-09-30 19:35:46 -0400
commit566ce93135c5762f5a2708dccf8a8b573f42438c (patch)
tree5352aaaa5453b72f7e941d9f0b1f82728775aecc
parentd3cd3d2b8f84f87d9f6bc32d085fb5741771857b (diff)
downloadrneovim-566ce93135c5762f5a2708dccf8a8b573f42438c.tar.gz
rneovim-566ce93135c5762f5a2708dccf8a8b573f42438c.tar.bz2
rneovim-566ce93135c5762f5a2708dccf8a8b573f42438c.zip
vim-patch:7.4.248
Problem: Cannot distinguish between NL and NUL in output of system(). Solution: Add systemlist(). (ZyX) https://code.google.com/p/vim/source/detail?r=v7-4-248
-rw-r--r--src/nvim/eval.c58
-rw-r--r--src/nvim/ex_cmds2.c4
-rw-r--r--src/nvim/misc1.c9
-rw-r--r--src/nvim/path.c2
-rw-r--r--src/nvim/version.c2
5 files changed, 62 insertions, 13 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 80ae356ef7..8af7965dfc 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -6543,6 +6543,7 @@ static struct fst {
{"synconcealed", 2, 2, f_synconcealed},
{"synstack", 2, 2, f_synstack},
{"system", 1, 2, f_system},
+ {"systemlist", 1, 2, f_systemlist},
{"tabpagebuflist", 0, 1, f_tabpagebuflist},
{"tabpagenr", 0, 1, f_tabpagenr},
{"tabpagewinnr", 1, 2, f_tabpagewinnr},
@@ -9873,7 +9874,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
"spell",
"syntax",
#if !defined(UNIX)
- "system",
+ "system", // TODO(SplinterOfChaos): This IS defined for UNIX!
#endif
"tag_binary",
"tag_old_static",
@@ -14415,8 +14416,8 @@ static void f_synstack(typval_T *argvars, typval_T *rettv)
}
}
-/// f_system - the VimL system() function
-static void f_system(typval_T *argvars, typval_T *rettv)
+static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
+ bool retlist)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -14453,9 +14454,41 @@ static void f_system(typval_T *argvars, typval_T *rettv)
set_vim_var_nr(VV_SHELL_ERROR, (long) status);
+ if (res == NULL) {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ return;
+ }
+
+ if (retlist) {
+ list_T *list = list_alloc();
+
+ // Copy each line to a list element using NL as the delimiter.
+ for (size_t i = 0; i < nread; i++) {
+ char_u *start = (char_u *) res + i;
+ size_t len = (char_u *) xmemscan(start, NL, nread - i) - start;
+ i += len;
+
+ char_u *s = vim_strnsave(start, len);
+ for (size_t j = 0; j < len; j++) {
+ if (s[j] == NUL) {
+ s[j] = NL;
+ }
+ }
+
+ listitem_T *li = listitem_alloc();
+ li->li_tv.v_type = VAR_STRING;
+ li->li_tv.vval.v_string = s;
+ list_append(list, li);
+ }
+
+ free(res);
+
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = list;
+ } else {
#ifdef USE_CRNL
- // translate <CR><NL> into <NL>
- if (res != NULL) {
+ // translate <CR><NL> into <NL>
char *d = res;
for (char *s = res; *s; ++s) {
if (s[0] == CAR && s[1] == NL) {
@@ -14466,12 +14499,23 @@ static void f_system(typval_T *argvars, typval_T *rettv)
}
*d = NUL;
- }
#endif
+ rettv->vval.v_string = (char_u *) res;
+ }
+}
- rettv->vval.v_string = (char_u *) res;
+/// f_system - the VimL system() function
+static void f_system(typval_T *argvars, typval_T *rettv)
+{
+ get_system_output_as_rettv(argvars, rettv, false);
+}
+
+static void f_systemlist(typval_T *argvars, typval_T *rettv)
+{
+ get_system_output_as_rettv(argvars, rettv, true);
}
+
/*
* "tabpagebuflist()" function
*/
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 0703c76b8a..056a101d47 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -3181,8 +3181,8 @@ static char_u **find_locales(void)
/* Find all available locales by running command "locale -a". If this
* doesn't work we won't have completion. */
- char_u *locale_a = get_cmd_output((char_u *)"locale -a",
- NULL, kShellOptSilent);
+ char_u *locale_a = get_cmd_output((char_u *)"locale -a", NULL,
+ kShellOptSilent, NULL);
if (locale_a == NULL)
return NULL;
ga_init(&locales_ga, sizeof(char_u *), 20);
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 52780b9a57..f832fa25f2 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -3401,13 +3401,16 @@ void fast_breakcheck(void)
/*
* Get the stdout of an external command.
+ * If "ret_len" is NULL replace NUL characters with NL. When "ret_len" is not
+ * NULL store the length there.
* Returns an allocated string, or NULL for error.
*/
char_u *
get_cmd_output (
char_u *cmd,
char_u *infile, /* optional input file name */
- int flags /* can be SHELL_SILENT */
+ int flags, // can be kShellOptSilent
+ size_t *ret_len
)
{
char_u *tempname;
@@ -3463,13 +3466,15 @@ get_cmd_output (
EMSG2(_(e_notread), tempname);
free(buffer);
buffer = NULL;
- } else {
+ } else if (ret_len == NULL) {
/* Change NUL into SOH, otherwise the string is truncated. */
for (i = 0; i < len; ++i)
if (buffer[i] == NUL)
buffer[i] = 1;
buffer[len] = NUL; /* make sure the buffer is terminated */
+ } else {
+ *ret_len = len;
}
done:
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 6990a1817c..ff97b7774a 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -1172,7 +1172,7 @@ expand_backtick (
buffer = eval_to_string(cmd + 1, &p, TRUE);
else
buffer = get_cmd_output(cmd, NULL,
- (flags & EW_SILENT) ? kShellOptSilent : 0);
+ (flags & EW_SILENT) ? kShellOptSilent : 0, NULL);
free(cmd);
if (buffer == NULL)
return 0;
diff --git a/src/nvim/version.c b/src/nvim/version.c
index ab609bf492..a453c0ee10 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -393,7 +393,7 @@ static int included_patches[] = {
251,
//250 NA
//249,
- //248,
+ 248,
247,
//246,
245,