0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 7.4.1644

Problem:    Using string() on a partial that exists in the dictionary it binds
            results in an error. (Nikolai Pavlov)
Solution:   Make string() not fail on a recursively nested structure. (Ken
            Takta)
This commit is contained in:
Bram Moolenaar
2016-03-24 21:23:06 +01:00
parent d4caf5c16a
commit 24c77a1e3a
3 changed files with 62 additions and 49 deletions

View File

@@ -7851,10 +7851,50 @@ echo_string(
break;
case VAR_PARTIAL:
*tofree = NULL;
/* TODO: arguments */
r = tv->vval.v_partial == NULL ? NULL : tv->vval.v_partial->pt_name;
break;
{
partial_T *pt = tv->vval.v_partial;
char_u *fname = string_quote(pt == NULL ? NULL
: pt->pt_name, FALSE);
garray_T ga;
int i;
char_u *tf;
ga_init2(&ga, 1, 100);
ga_concat(&ga, (char_u *)"function(");
if (fname != NULL)
{
ga_concat(&ga, fname);
vim_free(fname);
}
if (pt != NULL && pt->pt_argc > 0)
{
ga_concat(&ga, (char_u *)", [");
for (i = 0; i < pt->pt_argc; ++i)
{
if (i > 0)
ga_concat(&ga, (char_u *)", ");
ga_concat(&ga,
tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
vim_free(tf);
}
ga_concat(&ga, (char_u *)"]");
}
if (pt != NULL && pt->pt_dict != NULL)
{
typval_T dtv;
ga_concat(&ga, (char_u *)", ");
dtv.v_type = VAR_DICT;
dtv.vval.v_dict = pt->pt_dict;
ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
vim_free(tf);
}
ga_concat(&ga, (char_u *)")");
*tofree = ga.ga_data;
r = *tofree;
break;
}
case VAR_LIST:
if (tv->vval.v_list == NULL)
@@ -7941,50 +7981,6 @@ tv2string(
case VAR_FUNC:
*tofree = string_quote(tv->vval.v_string, TRUE);
return *tofree;
case VAR_PARTIAL:
{
partial_T *pt = tv->vval.v_partial;
char_u *fname = string_quote(pt == NULL ? NULL
: pt->pt_name, FALSE);
garray_T ga;
int i;
char_u *tf;
ga_init2(&ga, 1, 100);
ga_concat(&ga, (char_u *)"function(");
if (fname != NULL)
{
ga_concat(&ga, fname);
vim_free(fname);
}
if (pt != NULL && pt->pt_argc > 0)
{
ga_concat(&ga, (char_u *)", [");
for (i = 0; i < pt->pt_argc; ++i)
{
if (i > 0)
ga_concat(&ga, (char_u *)", ");
ga_concat(&ga,
tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
vim_free(tf);
}
ga_concat(&ga, (char_u *)"]");
}
if (pt != NULL && pt->pt_dict != NULL)
{
typval_T dtv;
ga_concat(&ga, (char_u *)", ");
dtv.v_type = VAR_DICT;
dtv.vval.v_dict = pt->pt_dict;
ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
vim_free(tf);
}
ga_concat(&ga, (char_u *)")");
*tofree = ga.ga_data;
return *tofree;
}
case VAR_STRING:
*tofree = string_quote(tv->vval.v_string, FALSE);
return *tofree;
@@ -7997,6 +7993,7 @@ tv2string(
case VAR_NUMBER:
case VAR_LIST:
case VAR_DICT:
case VAR_PARTIAL:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
@@ -19258,7 +19255,8 @@ f_string(typval_T *argvars, typval_T *rettv)
char_u numbuf[NUMBUFLEN];
rettv->v_type = VAR_STRING;
rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf,
get_copyID());
/* Make a copy if we have a value but it's not in allocated memory. */
if (rettv->vval.v_string != NULL && tofree == NULL)
rettv->vval.v_string = vim_strsave(rettv->vval.v_string);

View File

@@ -180,3 +180,16 @@ func Test_func_unref()
unlet obj
call assert_false(exists('*{' . funcnumber . '}'))
endfunc
func Test_tostring()
let d = {}
let d.d = d
function d.test3()
echo 42
endfunction
try
call string(d.test3)
catch
call assert_true(v:false, v:exception)
endtry
endfunc

View File

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