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
This commit is contained in:
Scott Prager
2014-09-04 23:44:24 -04:00
parent d3cd3d2b8f
commit 566ce93135
5 changed files with 63 additions and 14 deletions

View File

@@ -6543,6 +6543,7 @@ static struct fst {
{"synconcealed", 2, 2, f_synconcealed}, {"synconcealed", 2, 2, f_synconcealed},
{"synstack", 2, 2, f_synstack}, {"synstack", 2, 2, f_synstack},
{"system", 1, 2, f_system}, {"system", 1, 2, f_system},
{"systemlist", 1, 2, f_systemlist},
{"tabpagebuflist", 0, 1, f_tabpagebuflist}, {"tabpagebuflist", 0, 1, f_tabpagebuflist},
{"tabpagenr", 0, 1, f_tabpagenr}, {"tabpagenr", 0, 1, f_tabpagenr},
{"tabpagewinnr", 1, 2, f_tabpagewinnr}, {"tabpagewinnr", 1, 2, f_tabpagewinnr},
@@ -9873,7 +9874,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
"spell", "spell",
"syntax", "syntax",
#if !defined(UNIX) #if !defined(UNIX)
"system", "system", // TODO(SplinterOfChaos): This IS defined for UNIX!
#endif #endif
"tag_binary", "tag_binary",
"tag_old_static", "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 get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
static void f_system(typval_T *argvars, typval_T *rettv) bool retlist)
{ {
rettv->v_type = VAR_STRING; rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL; 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); 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 #ifdef USE_CRNL
// translate <CR><NL> into <NL> // translate <CR><NL> into <NL>
if (res != NULL) {
char *d = res; char *d = res;
for (char *s = res; *s; ++s) { for (char *s = res; *s; ++s) {
if (s[0] == CAR && s[1] == NL) { if (s[0] == CAR && s[1] == NL) {
@@ -14466,11 +14499,22 @@ static void f_system(typval_T *argvars, typval_T *rettv)
} }
*d = NUL; *d = NUL;
}
#endif #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 * "tabpagebuflist()" function

View File

@@ -3181,8 +3181,8 @@ static char_u **find_locales(void)
/* Find all available locales by running command "locale -a". If this /* Find all available locales by running command "locale -a". If this
* doesn't work we won't have completion. */ * doesn't work we won't have completion. */
char_u *locale_a = get_cmd_output((char_u *)"locale -a", char_u *locale_a = get_cmd_output((char_u *)"locale -a", NULL,
NULL, kShellOptSilent); kShellOptSilent, NULL);
if (locale_a == NULL) if (locale_a == NULL)
return NULL; return NULL;
ga_init(&locales_ga, sizeof(char_u *), 20); ga_init(&locales_ga, sizeof(char_u *), 20);

View File

@@ -3401,13 +3401,16 @@ void fast_breakcheck(void)
/* /*
* Get the stdout of an external command. * 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. * Returns an allocated string, or NULL for error.
*/ */
char_u * char_u *
get_cmd_output ( get_cmd_output (
char_u *cmd, char_u *cmd,
char_u *infile, /* optional input file name */ 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; char_u *tempname;
@@ -3463,13 +3466,15 @@ get_cmd_output (
EMSG2(_(e_notread), tempname); EMSG2(_(e_notread), tempname);
free(buffer); free(buffer);
buffer = NULL; buffer = NULL;
} else { } else if (ret_len == NULL) {
/* Change NUL into SOH, otherwise the string is truncated. */ /* Change NUL into SOH, otherwise the string is truncated. */
for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
if (buffer[i] == NUL) if (buffer[i] == NUL)
buffer[i] = 1; buffer[i] = 1;
buffer[len] = NUL; /* make sure the buffer is terminated */ buffer[len] = NUL; /* make sure the buffer is terminated */
} else {
*ret_len = len;
} }
done: done:

View File

@@ -1172,7 +1172,7 @@ expand_backtick (
buffer = eval_to_string(cmd + 1, &p, TRUE); buffer = eval_to_string(cmd + 1, &p, TRUE);
else else
buffer = get_cmd_output(cmd, NULL, buffer = get_cmd_output(cmd, NULL,
(flags & EW_SILENT) ? kShellOptSilent : 0); (flags & EW_SILENT) ? kShellOptSilent : 0, NULL);
free(cmd); free(cmd);
if (buffer == NULL) if (buffer == NULL)
return 0; return 0;

View File

@@ -393,7 +393,7 @@ static int included_patches[] = {
251, 251,
//250 NA //250 NA
//249, //249,
//248, 248,
247, 247,
//246, //246,
245, 245,