diff options
author | Bram Moolenaar <Bram@vim.org> | 2023-03-09 22:06:49 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2023-03-09 22:06:49 +0000 |
commit | be19d78c3d44221cbc38fbb5bac19302345c1def (patch) | |
tree | 1a1e07ad5501f660705c69190d76526e1acae4e6 | |
parent | 638388b8ef37684e36a7f5d9286bab2d31c28f36 (diff) |
patch 9.0.1396: sort(list, 'N') does not work in Vim9 script contextv9.0.1396
Problem: sort(list, 'N') does not work in Vim9 script context.
Solution: Convert string to number without giving an error. (closes #12061)
-rw-r--r-- | runtime/doc/builtin.txt | 5 | ||||
-rw-r--r-- | src/list.c | 6 | ||||
-rw-r--r-- | src/proto/typval.pro | 1 | ||||
-rw-r--r-- | src/testdir/test_sort.vim | 1 | ||||
-rw-r--r-- | src/typval.c | 26 | ||||
-rw-r--r-- | src/version.c | 2 |
6 files changed, 31 insertions, 10 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index a695547eeb..da2bf32f7d 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -8641,8 +8641,9 @@ sort({list} [, {how} [, {dict}]]) *sort()* *E702* When {how} is given and it is 'n' then all items will be sorted numerical (Implementation detail: this uses the - strtod() function to parse numbers, Strings, Lists, Dicts and - Funcrefs will be considered as being 0). + strtod() function to parse numbers. Strings, Lists, Dicts and + Funcrefs will be considered as being 0). Note that this won't + sort a list of strings with numbers! When {how} is given and it is 'N' then all items will be sorted numerical. This is like 'n' but a string containing diff --git a/src/list.c b/src/list.c index ae9e3e957a..991be8b01f 100644 --- a/src/list.c +++ b/src/list.c @@ -1910,8 +1910,8 @@ item_compare(const void *s1, const void *s2) if (sortinfo->item_compare_numbers) { - varnumber_T v1 = tv_get_number(tv1); - varnumber_T v2 = tv_get_number(tv2); + varnumber_T v1 = tv_to_number(tv1); + varnumber_T v2 = tv_to_number(tv2); return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; } @@ -2831,7 +2831,7 @@ extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new) } else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) { - // Check that extend() does not change the type of the list if it was + // Check that extend() does not change the type of the dict if it was // declared. if (!is_new && in_vim9script() && argvars[0].vval.v_dict != NULL) type = argvars[0].vval.v_dict->dv_type; diff --git a/src/proto/typval.pro b/src/proto/typval.pro index f3184d0250..8cecdb8d81 100644 --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -5,6 +5,7 @@ void free_tv(typval_T *varp); void clear_tv(typval_T *varp); void init_tv(typval_T *varp); varnumber_T tv_get_number(typval_T *varp); +varnumber_T tv_to_number(typval_T *varp); varnumber_T tv_get_number_chk(typval_T *varp, int *denote); varnumber_T tv_get_bool(typval_T *varp); varnumber_T tv_get_bool_chk(typval_T *varp, int *denote); diff --git a/src/testdir/test_sort.vim b/src/testdir/test_sort.vim index a2731a8004..14a70cf934 100644 --- a/src/testdir/test_sort.vim +++ b/src/testdir/test_sort.vim @@ -58,6 +58,7 @@ endfunc func Test_sort_numbers() call assert_equal([3, 13, 28], sort([13, 28, 3], 'N')) call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N')) + vim9cmd call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N')) call assert_equal([3997, 4996], sort([4996, 3997], 'Compare1')) endfunc diff --git a/src/typval.c b/src/typval.c index 10932e5665..a760f356bf 100644 --- a/src/typval.c +++ b/src/typval.c @@ -188,7 +188,11 @@ init_tv(typval_T *varp) } static varnumber_T -tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool) +tv_get_bool_or_number_chk( + typval_T *varp, + int *denote, + int want_bool, + int vim9_string_error) // in Vim9 using a string is an error { varnumber_T n = 0L; @@ -210,7 +214,7 @@ tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool) emsg(_(e_using_funcref_as_number)); break; case VAR_STRING: - if (in_vim9script()) + if (vim9_string_error && in_vim9script()) { emsg_using_string_as(varp, !want_bool); break; @@ -287,10 +291,22 @@ tv_get_number(typval_T *varp) return tv_get_number_chk(varp, &error); // return 0L on error } +/* + * Like tv_get_numbe() but in Vim9 script do convert a number in a string to a + * number without giving an error. + */ + varnumber_T +tv_to_number(typval_T *varp) +{ + int error = FALSE; + + return tv_get_bool_or_number_chk(varp, &error, FALSE, FALSE); +} + varnumber_T tv_get_number_chk(typval_T *varp, int *denote) { - return tv_get_bool_or_number_chk(varp, denote, FALSE); + return tv_get_bool_or_number_chk(varp, denote, FALSE, TRUE); } /* @@ -300,7 +316,7 @@ tv_get_number_chk(typval_T *varp, int *denote) varnumber_T tv_get_bool(typval_T *varp) { - return tv_get_bool_or_number_chk(varp, NULL, TRUE); + return tv_get_bool_or_number_chk(varp, NULL, TRUE, TRUE); } /* @@ -310,7 +326,7 @@ tv_get_bool(typval_T *varp) varnumber_T tv_get_bool_chk(typval_T *varp, int *denote) { - return tv_get_bool_or_number_chk(varp, denote, TRUE); + return tv_get_bool_or_number_chk(varp, denote, TRUE, TRUE); } static float_T diff --git a/src/version.c b/src/version.c index 82d89c1ce5..24c6fa307e 100644 --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1396, +/**/ 1395, /**/ 1394, |