Patch 8.2.2449
Problem: Vim9: flatten() always changes the list type.
Solution: Disallow using flatten() and add flattennew().
Files: runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/evalfunc.c,
src/list.c, src/proto/list.pro, src/errors.h, src/vim9compile.c,
src/testdir/test_flatten.vim, src/testdir/test_vim9_builtin.vim
*** ../vim-8.2.2448/runtime/doc/eval.txt 2021-01-31 17:02:06.250490190
+0100
--- runtime/doc/eval.txt 2021-02-01 19:48:59.899320314 +0100
***************
*** 2549,2554 ****
--- 2549,2556 ----
findfile({name} [, {path} [, {count}]])
String find file {name} in {path}
flatten({list} [, {maxdepth}]) List flatten {list} up to {maxdepth}
levels
+ flattennew({list} [, {maxdepth}])
+ List flatten a copy of {list}
float2nr({expr}) Number convert Float {expr} to a Number
floor({expr}) Float round {expr} down
fmod({expr1}, {expr2}) Float remainder of {expr1} / {expr2}
***************
*** 4712,4719 ****
Flatten {list} up to {maxdepth} levels. Without {maxdepth}
the result is a |List| without nesting, as if {maxdepth} is
a very large number.
! The {list} is changed in place, make a copy first if you do
not want that.
*E900*
{maxdepth} means how deep in nested lists changes are made.
{list} is not modified when {maxdepth} is 0.
--- 4714,4723 ----
Flatten {list} up to {maxdepth} levels. Without {maxdepth}
the result is a |List| without nesting, as if {maxdepth} is
a very large number.
! The {list} is changed in place, use |flattennew()| if you do
not want that.
+ In Vim9 script flatten() cannot be used, you must always use
+ |flattennew()|.
*E900*
{maxdepth} means how deep in nested lists changes are made.
{list} is not modified when {maxdepth} is 0.
***************
*** 4727,4732 ****
--- 4731,4740 ----
:echo flatten([1, [2, [3, 4]], 5], 1)
< [1, 2, [3, 4], 5]
+ flattennew({list} [, {maxdepth}]) *flattennew()*
+ Like |flatten()| but first make a copy of {list}.
+
+
float2nr({expr}) *float2nr()*
Convert {expr} to a Number by omitting the part after the
decimal point.
*** ../vim-8.2.2448/runtime/doc/usr_41.txt 2021-01-31 17:02:06.266490126
+0100
--- runtime/doc/usr_41.txt 2021-02-01 19:49:35.455237261 +0100
***************
*** 665,670 ****
--- 665,671 ----
count() count number of times a value appears in a List
repeat() repeat a List multiple times
flatten() flatten a List
+ flattennew() flatten a copy of a List
Dictionary manipulation: *dict-functions*
get() get an entry without an error for a wrong key
*** ../vim-8.2.2448/src/evalfunc.c 2021-01-31 20:48:55.162175817 +0100
--- src/evalfunc.c 2021-02-01 19:50:24.523120307 +0100
***************
*** 954,959 ****
--- 954,961 ----
ret_string, f_findfile},
{"flatten", 1, 2, FEARG_1, NULL,
ret_list_any, f_flatten},
+ {"flattennew", 1, 2, FEARG_1, NULL,
+ ret_list_any, f_flattennew},
{"float2nr", 1, 1, FEARG_1, NULL,
ret_number, FLOAT_FUNC(f_float2nr)},
{"floor", 1, 1, FEARG_1, NULL,
*** ../vim-8.2.2448/src/list.c 2021-01-31 17:48:26.358330166 +0100
--- src/list.c 2021-02-01 20:03:02.281100687 +0100
***************
*** 740,746 ****
* It does nothing if "maxdepth" is 0.
* Returns FAIL when out of memory.
*/
! static int
list_flatten(list_T *list, long maxdepth)
{
listitem_T *item;
--- 740,746 ----
* It does nothing if "maxdepth" is 0.
* Returns FAIL when out of memory.
*/
! static void
list_flatten(list_T *list, long maxdepth)
{
listitem_T *item;
***************
*** 748,754 ****
int n;
if (maxdepth == 0)
! return OK;
CHECK_LIST_MATERIALIZE(list);
n = 0;
--- 748,754 ----
int n;
if (maxdepth == 0)
! return;
CHECK_LIST_MATERIALIZE(list);
n = 0;
***************
*** 757,763 ****
{
fast_breakcheck();
if (got_int)
! return FAIL;
if (item->li_tv.v_type == VAR_LIST)
{
--- 757,763 ----
{
fast_breakcheck();
if (got_int)
! return;
if (item->li_tv.v_type == VAR_LIST)
{
***************
*** 765,771 ****
vimlist_remove(list, item, item);
if (list_extend(list, item->li_tv.vval.v_list, next) == FAIL)
! return FAIL;
clear_tv(&item->li_tv);
tofree = item;
--- 765,771 ----
vimlist_remove(list, item, item);
if (list_extend(list, item->li_tv.vval.v_list, next) == FAIL)
! return;
clear_tv(&item->li_tv);
tofree = item;
***************
*** 787,801 ****
item = item->li_next;
}
}
-
- return OK;
}
/*
! * "flatten(list[, {maxdepth}])" function
*/
! void
! f_flatten(typval_T *argvars, typval_T *rettv)
{
list_T *l;
long maxdepth;
--- 787,799 ----
item = item->li_next;
}
}
}
/*
! * "flatten()" and "flattennew()" functions
*/
! static void
! flatten_common(typval_T *argvars, typval_T *rettv, int make_copy)
{
list_T *l;
long maxdepth;
***************
*** 822,831 ****
}
l = argvars[0].vval.v_list;
! if (l != NULL && !value_check_lock(l->lv_lock,
! (char_u *)N_("flatten() argument"), TRUE)
! && list_flatten(l, maxdepth) == OK)
! copy_tv(&argvars[0], rettv);
}
/*
--- 820,867 ----
}
l = argvars[0].vval.v_list;
! rettv->v_type = VAR_LIST;
! rettv->vval.v_list = l;
! if (l == NULL)
! return;
!
! if (make_copy)
! {
! l = list_copy(l, TRUE, get_copyID());
! rettv->vval.v_list = l;
! if (l == NULL)
! return;
! }
! else
! {
! if (value_check_lock(l->lv_lock,
! (char_u *)N_("flatten() argument"), TRUE))
! return;
! ++l->lv_refcount;
! }
!
! list_flatten(l, maxdepth);
! }
!
! /*
! * "flatten(list[, {maxdepth}])" function
! */
! void
! f_flatten(typval_T *argvars, typval_T *rettv)
! {
! if (in_vim9script())
! emsg(_(e_cannot_use_flatten_in_vim9_script));
! else
! flatten_common(argvars, rettv, FALSE);
! }
!
! /*
! * "flattennew(list[, {maxdepth}])" function
! */
! void
! f_flattennew(typval_T *argvars, typval_T *rettv)
! {
! flatten_common(argvars, rettv, TRUE);
}
/*
*** ../vim-8.2.2448/src/proto/list.pro 2021-01-13 21:46:53.832589880 +0100
--- src/proto/list.pro 2021-02-01 19:54:08.770557406 +0100
***************
*** 31,36 ****
--- 31,37 ----
int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
void list_insert(list_T *l, listitem_T *ni, listitem_T *item);
void f_flatten(typval_T *argvars, typval_T *rettv);
+ void f_flattennew(typval_T *argvars, typval_T *rettv);
int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
int list_concat(list_T *l1, list_T *l2, typval_T *tv);
list_T *list_slice(list_T *ol, long n1, long n2);
*** ../vim-8.2.2448/src/errors.h 2021-01-31 22:18:21.977811108 +0100
--- src/errors.h 2021-02-01 19:54:23.870518098 +0100
***************
*** 351,353 ****
--- 351,355 ----
INIT(= N_("E1156: Cannot change the argument list recursively"));
EXTERN char e_missing_return_type[]
INIT(= N_("E1157: Missing return type"));
+ EXTERN char e_cannot_use_flatten_in_vim9_script[]
+ INIT(= N_("E1158: Cannot use flatten() in Vim9 script"));
*** ../vim-8.2.2448/src/vim9compile.c 2021-01-31 21:47:39.036783041 +0100
--- src/vim9compile.c 2021-02-01 20:11:35.063630218 +0100
***************
*** 2900,2905 ****
--- 2900,2911 ----
idx = find_internal_func(name);
if (idx >= 0)
{
+ if (STRCMP(name, "flatten") == 0)
+ {
+ emsg(_(e_cannot_use_flatten_in_vim9_script));
+ goto theend;
+ }
+
if (STRCMP(name, "add") == 0 && argcount == 2)
{
garray_T *stack = &cctx->ctx_type_stack;
*** ../vim-8.2.2448/src/testdir/test_flatten.vim 2020-08-12
18:50:31.879655802 +0200
--- src/testdir/test_flatten.vim 2021-02-01 20:06:39.924481595 +0100
***************
*** 81,84 ****
--- 81,93 ----
call assert_equal([2, l:x], l:y)
endfunc
+ func Test_flattennew()
+ let l = [1, [2, [3, 4]], 5]
+ call assert_equal([1, 2, 3, 4, 5], flattennew(l))
+ call assert_equal([1, [2, [3, 4]], 5], l)
+
+ call assert_equal([1, 2, [3, 4], 5], flattennew(l, 1))
+ call assert_equal([1, [2, [3, 4]], 5], l)
+ endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.2448/src/testdir/test_vim9_builtin.vim 2021-01-31
20:48:55.162175817 +0100
--- src/testdir/test_vim9_builtin.vim 2021-02-01 20:09:18.728024772 +0100
***************
*** 382,387 ****
--- 382,404 ----
CheckDefExecFailure(['echo findfile("")'], 'E1142:')
enddef
+ def Test_flattennew()
+ var lines =<< trim END
+ var l = [1, [2, [3, 4]], 5]
+ call assert_equal([1, 2, 3, 4, 5], flattennew(l))
+ call assert_equal([1, [2, [3, 4]], 5], l)
+
+ call assert_equal([1, 2, [3, 4], 5], flattennew(l, 1))
+ call assert_equal([1, [2, [3, 4]], 5], l)
+ END
+ CheckDefAndScriptSuccess(lines)
+
+ lines =<< trim END
+ echo flatten([1, 2, 3])
+ END
+ CheckDefAndScriptFailure(lines, 'E1158:')
+ enddef
+
def Test_fnamemodify()
CheckDefSuccess(['echo fnamemodify(test_null_string(), ":p")'])
CheckDefSuccess(['echo fnamemodify("", ":p")'])
*** ../vim-8.2.2448/src/version.c 2021-02-01 19:31:43.969603658 +0100
--- src/version.c 2021-02-01 19:51:03.851024757 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2449,
/**/
--
Facepalm reply #9: "Speed up, you can drive 80 here" "Why, the cars behind us
are also driving 60"
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202102011915.111JFKhP1304916%40masaka.moolenaar.net.