1
0
forked from aniani/vim

patch 8.2.2356: Vim9: ":put =expr" does not handle a list properly

Problem:    Vim9: ":put =expr" does not handle a list properly.
Solution:   Use the same logic as eval_to_string_eap(). (closes #7684)
This commit is contained in:
Bram Moolenaar 2021-01-15 18:04:43 +01:00
parent 97c6943e11
commit 883cf97f10
5 changed files with 47 additions and 26 deletions

View File

@ -466,6 +466,45 @@ skip_expr_concatenate(
return res;
}
/*
* Convert "tv" to a string.
* When "convert" is TRUE convert a List into a sequence of lines and convert
* a Float to a String.
* Returns an allocated string (NULL when out of memory).
*/
char_u *
typval2string(typval_T *tv, int convert)
{
garray_T ga;
char_u *retval;
#ifdef FEAT_FLOAT
char_u numbuf[NUMBUFLEN];
#endif
if (convert && tv->v_type == VAR_LIST)
{
ga_init2(&ga, (int)sizeof(char), 80);
if (tv->vval.v_list != NULL)
{
list_join(&ga, tv->vval.v_list, (char_u *)"\n", TRUE, FALSE, 0);
if (tv->vval.v_list->lv_len > 0)
ga_append(&ga, NL);
}
ga_append(&ga, NUL);
retval = (char_u *)ga.ga_data;
}
#ifdef FEAT_FLOAT
else if (convert && tv->v_type == VAR_FLOAT)
{
vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
retval = vim_strsave(numbuf);
}
#endif
else
retval = vim_strsave(tv_get_string(tv));
return retval;
}
/*
* Top level evaluation function, returning a string. Does not handle line
* breaks.
@ -481,10 +520,6 @@ eval_to_string_eap(
{
typval_T tv;
char_u *retval;
garray_T ga;
#ifdef FEAT_FLOAT
char_u numbuf[NUMBUFLEN];
#endif
evalarg_T evalarg;
fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
@ -492,27 +527,7 @@ eval_to_string_eap(
retval = NULL;
else
{
if (convert && tv.v_type == VAR_LIST)
{
ga_init2(&ga, (int)sizeof(char), 80);
if (tv.vval.v_list != NULL)
{
list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, FALSE, 0);
if (tv.vval.v_list->lv_len > 0)
ga_append(&ga, NL);
}
ga_append(&ga, NUL);
retval = (char_u *)ga.ga_data;
}
#ifdef FEAT_FLOAT
else if (convert && tv.v_type == VAR_FLOAT)
{
vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
retval = vim_strsave(numbuf);
}
#endif
else
retval = vim_strsave(tv_get_string(&tv));
retval = typval2string(&tv, convert);
clear_tv(&tv);
}
clear_evalarg(&evalarg, NULL);

View File

@ -11,6 +11,7 @@ int eval_expr_to_bool(typval_T *expr, int *error);
char_u *eval_to_string_skip(char_u *arg, exarg_T *eap, int skip);
int skip_expr(char_u **pp, evalarg_T *evalarg);
int skip_expr_concatenate(char_u **arg, char_u **start, char_u **end, evalarg_T *evalarg);
char_u *typval2string(typval_T *tv, int convert);
char_u *eval_to_string_eap(char_u *arg, int convert, exarg_T *eap);
char_u *eval_to_string(char_u *arg, int convert);
char_u *eval_to_string_safe(char_u *arg, int use_sandbox);

View File

@ -736,6 +736,9 @@ def Test_put_command()
assert_equal('above', getline(3))
assert_equal('below', getline(4))
:2put =['a', 'b', 'c']
assert_equal(['ppp', 'a', 'b', 'c', 'above'], getline(2, 6))
# compute range at runtime
setline(1, range(1, 8))
@a = 'aaa'

View File

@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2356,
/**/
2355,
/**/

View File

@ -3357,7 +3357,7 @@ call_def_function(
expr = tv->vval.v_string;
else
{
expr = typval_tostring(tv); // allocates value
expr = typval2string(tv, TRUE); // allocates value
clear_tv(tv);
}
--ectx.ec_stack.ga_len;