mirror of
https://github.com/vim/vim.git
synced 2025-09-29 04:34:16 -04:00
patch 7.4.1862
Problem: string() with repeated argument does not give a result usable by eval(). Solution: Refactor echo_striong and tv2string(), moving the common part to echo_string_core(). (Ken Takata)
This commit is contained in:
134
src/eval.c
134
src/eval.c
@@ -445,16 +445,17 @@ static long list_idx_of_item(list_T *l, listitem_T *item);
|
|||||||
static int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
|
static int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
|
||||||
static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
|
static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
|
||||||
static list_T *list_copy(list_T *orig, int deep, int copyID);
|
static list_T *list_copy(list_T *orig, int deep, int copyID);
|
||||||
static char_u *list2string(typval_T *tv, int copyID);
|
static char_u *list2string(typval_T *tv, int copyID, int restore_copyID);
|
||||||
static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap);
|
static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID, garray_T *join_gap);
|
||||||
static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID);
|
static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID);
|
||||||
static int free_unref_items(int copyID);
|
static int free_unref_items(int copyID);
|
||||||
static dictitem_T *dictitem_copy(dictitem_T *org);
|
static dictitem_T *dictitem_copy(dictitem_T *org);
|
||||||
static void dictitem_remove(dict_T *dict, dictitem_T *item);
|
static void dictitem_remove(dict_T *dict, dictitem_T *item);
|
||||||
static dict_T *dict_copy(dict_T *orig, int deep, int copyID);
|
static dict_T *dict_copy(dict_T *orig, int deep, int copyID);
|
||||||
static long dict_len(dict_T *d);
|
static long dict_len(dict_T *d);
|
||||||
static char_u *dict2string(typval_T *tv, int copyID);
|
static char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
|
||||||
static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
|
static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
|
||||||
|
static char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int dict_val);
|
||||||
static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
|
static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
|
||||||
static char_u *string_quote(char_u *str, int function);
|
static char_u *string_quote(char_u *str, int function);
|
||||||
static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
|
static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
|
||||||
@@ -1462,7 +1463,7 @@ eval_to_string(
|
|||||||
ga_init2(&ga, (int)sizeof(char), 80);
|
ga_init2(&ga, (int)sizeof(char), 80);
|
||||||
if (tv.vval.v_list != NULL)
|
if (tv.vval.v_list != NULL)
|
||||||
{
|
{
|
||||||
list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0);
|
list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, FALSE, 0);
|
||||||
if (tv.vval.v_list->lv_len > 0)
|
if (tv.vval.v_list->lv_len > 0)
|
||||||
ga_append(&ga, NL);
|
ga_append(&ga, NL);
|
||||||
}
|
}
|
||||||
@@ -6766,7 +6767,7 @@ vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
|
|||||||
* May return NULL.
|
* May return NULL.
|
||||||
*/
|
*/
|
||||||
static char_u *
|
static char_u *
|
||||||
list2string(typval_T *tv, int copyID)
|
list2string(typval_T *tv, int copyID, int restore_copyID)
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
|
|
||||||
@@ -6774,7 +6775,8 @@ list2string(typval_T *tv, int copyID)
|
|||||||
return NULL;
|
return NULL;
|
||||||
ga_init2(&ga, (int)sizeof(char), 80);
|
ga_init2(&ga, (int)sizeof(char), 80);
|
||||||
ga_append(&ga, '[');
|
ga_append(&ga, '[');
|
||||||
if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL)
|
if (list_join(&ga, tv->vval.v_list, (char_u *)", ",
|
||||||
|
FALSE, restore_copyID, copyID) == FAIL)
|
||||||
{
|
{
|
||||||
vim_free(ga.ga_data);
|
vim_free(ga.ga_data);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -6795,6 +6797,7 @@ list_join_inner(
|
|||||||
list_T *l,
|
list_T *l,
|
||||||
char_u *sep,
|
char_u *sep,
|
||||||
int echo_style,
|
int echo_style,
|
||||||
|
int restore_copyID,
|
||||||
int copyID,
|
int copyID,
|
||||||
garray_T *join_gap) /* to keep each list item string */
|
garray_T *join_gap) /* to keep each list item string */
|
||||||
{
|
{
|
||||||
@@ -6811,10 +6814,8 @@ list_join_inner(
|
|||||||
/* Stringify each item in the list. */
|
/* Stringify each item in the list. */
|
||||||
for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
|
for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
|
||||||
{
|
{
|
||||||
if (echo_style)
|
s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
|
||||||
s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
|
echo_style, restore_copyID, FALSE);
|
||||||
else
|
|
||||||
s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
|
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
@@ -6873,6 +6874,7 @@ list_join(
|
|||||||
list_T *l,
|
list_T *l,
|
||||||
char_u *sep,
|
char_u *sep,
|
||||||
int echo_style,
|
int echo_style,
|
||||||
|
int restore_copyID,
|
||||||
int copyID)
|
int copyID)
|
||||||
{
|
{
|
||||||
garray_T join_ga;
|
garray_T join_ga;
|
||||||
@@ -6883,7 +6885,8 @@ list_join(
|
|||||||
if (l->lv_len < 1)
|
if (l->lv_len < 1)
|
||||||
return OK; /* nothing to do */
|
return OK; /* nothing to do */
|
||||||
ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
|
ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
|
||||||
retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
|
retval = list_join_inner(gap, l, sep, echo_style, restore_copyID,
|
||||||
|
copyID, &join_ga);
|
||||||
|
|
||||||
/* Dispose each item in join_ga. */
|
/* Dispose each item in join_ga. */
|
||||||
if (join_ga.ga_data != NULL)
|
if (join_ga.ga_data != NULL)
|
||||||
@@ -7833,7 +7836,7 @@ get_dict_number(dict_T *d, char_u *key)
|
|||||||
* May return NULL.
|
* May return NULL.
|
||||||
*/
|
*/
|
||||||
static char_u *
|
static char_u *
|
||||||
dict2string(typval_T *tv, int copyID)
|
dict2string(typval_T *tv, int copyID, int restore_copyID)
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
int first = TRUE;
|
int first = TRUE;
|
||||||
@@ -7868,7 +7871,8 @@ dict2string(typval_T *tv, int copyID)
|
|||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
}
|
}
|
||||||
ga_concat(&ga, (char_u *)": ");
|
ga_concat(&ga, (char_u *)": ");
|
||||||
s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
|
s = echo_string_core(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID,
|
||||||
|
FALSE, restore_copyID, TRUE);
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
ga_concat(&ga, s);
|
ga_concat(&ga, s);
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
@@ -8026,16 +8030,23 @@ get_var_special_name(int nr)
|
|||||||
* Return a string with the string representation of a variable.
|
* Return a string with the string representation of a variable.
|
||||||
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||||
* "numbuf" is used for a number.
|
* "numbuf" is used for a number.
|
||||||
* Does not put quotes around strings, as ":echo" displays values.
|
|
||||||
* When "copyID" is not NULL replace recursive lists and dicts with "...".
|
* When "copyID" is not NULL replace recursive lists and dicts with "...".
|
||||||
|
* When both "echo_style" and "dict_val" are FALSE, put quotes around stings as
|
||||||
|
* "string()", otherwise does not put quotes around strings, as ":echo"
|
||||||
|
* displays values.
|
||||||
|
* When "restore_copyID" is FALSE, repeated items in dictionaries and lists
|
||||||
|
* are replaced with "...".
|
||||||
* May return NULL.
|
* May return NULL.
|
||||||
*/
|
*/
|
||||||
static char_u *
|
static char_u *
|
||||||
echo_string(
|
echo_string_core(
|
||||||
typval_T *tv,
|
typval_T *tv,
|
||||||
char_u **tofree,
|
char_u **tofree,
|
||||||
char_u *numbuf,
|
char_u *numbuf,
|
||||||
int copyID)
|
int copyID,
|
||||||
|
int echo_style,
|
||||||
|
int restore_copyID,
|
||||||
|
int dict_val)
|
||||||
{
|
{
|
||||||
static int recurse = 0;
|
static int recurse = 0;
|
||||||
char_u *r = NULL;
|
char_u *r = NULL;
|
||||||
@@ -8057,9 +8068,30 @@ echo_string(
|
|||||||
|
|
||||||
switch (tv->v_type)
|
switch (tv->v_type)
|
||||||
{
|
{
|
||||||
|
case VAR_STRING:
|
||||||
|
if (echo_style && !dict_val)
|
||||||
|
{
|
||||||
|
*tofree = NULL;
|
||||||
|
r = get_tv_string_buf(tv, numbuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*tofree = string_quote(tv->vval.v_string, FALSE);
|
||||||
|
r = *tofree;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
*tofree = NULL;
|
if (echo_style)
|
||||||
r = tv->vval.v_string;
|
{
|
||||||
|
*tofree = NULL;
|
||||||
|
r = tv->vval.v_string;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*tofree = string_quote(tv->vval.v_string, TRUE);
|
||||||
|
r = *tofree;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_PARTIAL:
|
case VAR_PARTIAL:
|
||||||
@@ -8114,15 +8146,20 @@ echo_string(
|
|||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
r = NULL;
|
r = NULL;
|
||||||
}
|
}
|
||||||
else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
|
else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID
|
||||||
|
&& tv->vval.v_list->lv_len > 0)
|
||||||
{
|
{
|
||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
r = (char_u *)"[...]";
|
r = (char_u *)"[...]";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int old_copyID = tv->vval.v_list->lv_copyID;
|
||||||
|
|
||||||
tv->vval.v_list->lv_copyID = copyID;
|
tv->vval.v_list->lv_copyID = copyID;
|
||||||
*tofree = list2string(tv, copyID);
|
*tofree = list2string(tv, copyID, restore_copyID);
|
||||||
|
if (restore_copyID)
|
||||||
|
tv->vval.v_list->lv_copyID = old_copyID;
|
||||||
r = *tofree;
|
r = *tofree;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -8133,20 +8170,23 @@ echo_string(
|
|||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
r = NULL;
|
r = NULL;
|
||||||
}
|
}
|
||||||
else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
|
else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID
|
||||||
|
&& tv->vval.v_dict->dv_hashtab.ht_used != 0)
|
||||||
{
|
{
|
||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
r = (char_u *)"{...}";
|
r = (char_u *)"{...}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int old_copyID = tv->vval.v_dict->dv_copyID;
|
||||||
tv->vval.v_dict->dv_copyID = copyID;
|
tv->vval.v_dict->dv_copyID = copyID;
|
||||||
*tofree = dict2string(tv, copyID);
|
*tofree = dict2string(tv, copyID, restore_copyID);
|
||||||
|
if (restore_copyID)
|
||||||
|
tv->vval.v_dict->dv_copyID = old_copyID;
|
||||||
r = *tofree;
|
r = *tofree;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_STRING:
|
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_UNKNOWN:
|
case VAR_UNKNOWN:
|
||||||
case VAR_JOB:
|
case VAR_JOB:
|
||||||
@@ -8174,6 +8214,24 @@ echo_string(
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a string with the string representation of a variable.
|
||||||
|
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||||
|
* "numbuf" is used for a number.
|
||||||
|
* Does not put quotes around strings, as ":echo" displays values.
|
||||||
|
* When "copyID" is not NULL replace recursive lists and dicts with "...".
|
||||||
|
* May return NULL.
|
||||||
|
*/
|
||||||
|
static char_u *
|
||||||
|
echo_string(
|
||||||
|
typval_T *tv,
|
||||||
|
char_u **tofree,
|
||||||
|
char_u *numbuf,
|
||||||
|
int copyID)
|
||||||
|
{
|
||||||
|
return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a string with the string representation of a variable.
|
* Return a string with the string representation of a variable.
|
||||||
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||||
@@ -8188,31 +8246,7 @@ tv2string(
|
|||||||
char_u *numbuf,
|
char_u *numbuf,
|
||||||
int copyID)
|
int copyID)
|
||||||
{
|
{
|
||||||
switch (tv->v_type)
|
return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
|
||||||
{
|
|
||||||
case VAR_FUNC:
|
|
||||||
*tofree = string_quote(tv->vval.v_string, TRUE);
|
|
||||||
return *tofree;
|
|
||||||
case VAR_STRING:
|
|
||||||
*tofree = string_quote(tv->vval.v_string, FALSE);
|
|
||||||
return *tofree;
|
|
||||||
case VAR_FLOAT:
|
|
||||||
#ifdef FEAT_FLOAT
|
|
||||||
*tofree = NULL;
|
|
||||||
vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float);
|
|
||||||
return numbuf;
|
|
||||||
#endif
|
|
||||||
case VAR_NUMBER:
|
|
||||||
case VAR_LIST:
|
|
||||||
case VAR_DICT:
|
|
||||||
case VAR_PARTIAL:
|
|
||||||
case VAR_SPECIAL:
|
|
||||||
case VAR_JOB:
|
|
||||||
case VAR_CHANNEL:
|
|
||||||
case VAR_UNKNOWN:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return echo_string(tv, tofree, numbuf, copyID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -15182,7 +15216,7 @@ f_join(typval_T *argvars, typval_T *rettv)
|
|||||||
if (sep != NULL)
|
if (sep != NULL)
|
||||||
{
|
{
|
||||||
ga_init2(&ga, (int)sizeof(char), 80);
|
ga_init2(&ga, (int)sizeof(char), 80);
|
||||||
list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
|
list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0);
|
||||||
ga_append(&ga, NUL);
|
ga_append(&ga, NUL);
|
||||||
rettv->vval.v_string = (char_u *)ga.ga_data;
|
rettv->vval.v_string = (char_u *)ga.ga_data;
|
||||||
}
|
}
|
||||||
|
@@ -484,7 +484,7 @@ psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_reb
|
|||||||
psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
|
psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
|
||||||
psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
|
psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
|
||||||
psaC: <vim.Function 'SelfArgs'>
|
psaC: <vim.Function 'SelfArgs'>
|
||||||
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
|
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}]}>
|
||||||
s(a): function('Args')
|
s(a): function('Args')
|
||||||
s(pa1): function('Args', ['abcArgsPA1'])
|
s(pa1): function('Args', ['abcArgsPA1'])
|
||||||
s(pa2): function('Args')
|
s(pa2): function('Args')
|
||||||
|
@@ -484,7 +484,7 @@ psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_reb
|
|||||||
psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
|
psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
|
||||||
psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
|
psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
|
||||||
psaC: <vim.Function 'SelfArgs'>
|
psaC: <vim.Function 'SelfArgs'>
|
||||||
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
|
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}]}>
|
||||||
s(a): function('Args')
|
s(a): function('Args')
|
||||||
s(pa1): function('Args', ['abcArgsPA1'])
|
s(pa1): function('Args', ['abcArgsPA1'])
|
||||||
s(pa2): function('Args')
|
s(pa2): function('Args')
|
||||||
|
@@ -1052,6 +1052,150 @@ func Test_skip()
|
|||||||
|
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
"-------------------------------------------------------------------------------
|
||||||
|
" Test 93: :echo and string() {{{1
|
||||||
|
"-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func Test_echo_and_string()
|
||||||
|
" String
|
||||||
|
let a = 'foo bar'
|
||||||
|
redir => result
|
||||||
|
echo a
|
||||||
|
echo string(a)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["foo bar",
|
||||||
|
\ "'foo bar'"], l)
|
||||||
|
|
||||||
|
" Float
|
||||||
|
if has('float')
|
||||||
|
let a = -1.2e0
|
||||||
|
redir => result
|
||||||
|
echo a
|
||||||
|
echo string(a)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["-1.2",
|
||||||
|
\ "-1.2"], l)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Funcref
|
||||||
|
redir => result
|
||||||
|
echo function('string')
|
||||||
|
echo string(function('string'))
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["string",
|
||||||
|
\ "function('string')"], l)
|
||||||
|
|
||||||
|
" Recursive dictionary
|
||||||
|
let a = {}
|
||||||
|
let a["a"] = a
|
||||||
|
redir => result
|
||||||
|
echo a
|
||||||
|
echo string(a)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["{'a': {...}}",
|
||||||
|
\ "{'a': {...}}"], l)
|
||||||
|
|
||||||
|
" Recursive list
|
||||||
|
let a = [0]
|
||||||
|
let a[0] = a
|
||||||
|
redir => result
|
||||||
|
echo a
|
||||||
|
echo string(a)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["[[...]]",
|
||||||
|
\ "[[...]]"], l)
|
||||||
|
|
||||||
|
" Empty dictionaries in a list
|
||||||
|
let a = {}
|
||||||
|
redir => result
|
||||||
|
echo [a, a, a]
|
||||||
|
echo string([a, a, a])
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["[{}, {}, {}]",
|
||||||
|
\ "[{}, {}, {}]"], l)
|
||||||
|
|
||||||
|
" Empty dictionaries in a dictionary
|
||||||
|
let a = {}
|
||||||
|
let b = {"a": a, "b": a}
|
||||||
|
redir => result
|
||||||
|
echo b
|
||||||
|
echo string(b)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["{'a': {}, 'b': {}}",
|
||||||
|
\ "{'a': {}, 'b': {}}"], l)
|
||||||
|
|
||||||
|
" Empty lists in a list
|
||||||
|
let a = []
|
||||||
|
redir => result
|
||||||
|
echo [a, a, a]
|
||||||
|
echo string([a, a, a])
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["[[], [], []]",
|
||||||
|
\ "[[], [], []]"], l)
|
||||||
|
|
||||||
|
" Empty lists in a dictionary
|
||||||
|
let a = []
|
||||||
|
let b = {"a": a, "b": a}
|
||||||
|
redir => result
|
||||||
|
echo b
|
||||||
|
echo string(b)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["{'a': [], 'b': []}",
|
||||||
|
\ "{'a': [], 'b': []}"], l)
|
||||||
|
|
||||||
|
" Dictionaries in a list
|
||||||
|
let a = {"one": "yes", "two": "yes", "three": "yes"}
|
||||||
|
redir => result
|
||||||
|
echo [a, a, a]
|
||||||
|
echo string([a, a, a])
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
|
||||||
|
\ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
|
||||||
|
|
||||||
|
" Dictionaries in a dictionary
|
||||||
|
let a = {"one": "yes", "two": "yes", "three": "yes"}
|
||||||
|
let b = {"a": a, "b": a}
|
||||||
|
redir => result
|
||||||
|
echo b
|
||||||
|
echo string(b)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
|
||||||
|
\ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
|
||||||
|
|
||||||
|
" Lists in a list
|
||||||
|
let a = [1, 2, 3]
|
||||||
|
redir => result
|
||||||
|
echo [a, a, a]
|
||||||
|
echo string([a, a, a])
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["[[1, 2, 3], [...], [...]]",
|
||||||
|
\ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
|
||||||
|
|
||||||
|
" Lists in a dictionary
|
||||||
|
let a = [1, 2, 3]
|
||||||
|
let b = {"a": a, "b": a}
|
||||||
|
redir => result
|
||||||
|
echo b
|
||||||
|
echo string(b)
|
||||||
|
redir END
|
||||||
|
let l = split(result, "\n")
|
||||||
|
call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
|
||||||
|
\ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
|
||||||
|
|
||||||
|
endfunc
|
||||||
|
|
||||||
"-------------------------------------------------------------------------------
|
"-------------------------------------------------------------------------------
|
||||||
" Modelines {{{1
|
" Modelines {{{1
|
||||||
" vim: ts=8 sw=4 tw=80 fdm=marker
|
" vim: ts=8 sw=4 tw=80 fdm=marker
|
||||||
|
@@ -753,6 +753,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1862,
|
||||||
/**/
|
/**/
|
||||||
1861,
|
1861,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user