To: vim_dev@googlegroups.com Subject: Patch 9.0.1396 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1396 Problem: sort(list, 'N') does not work in Vim9 script context. Solution: Convert string to number without giving an error. (closes #12061) Files: runtime/doc/builtin.txt, src/list.c, src/typval.c, src/proto/typval.pro, src/testdir/test_sort.vim *** ../vim-9.0.1395/runtime/doc/builtin.txt 2023-01-24 12:33:58.946777427 +0000 --- runtime/doc/builtin.txt 2023-03-09 21:57:06.677861158 +0000 *************** *** 8634,8641 **** 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). When {how} is given and it is 'N' then all items will be sorted numerical. This is like 'n' but a string containing --- 8641,8649 ---- 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). 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 *** ../vim-9.0.1395/src/list.c 2023-03-07 17:45:07.184247900 +0000 --- src/list.c 2023-03-09 22:04:36.700110798 +0000 *************** *** 1910,1917 **** if (sortinfo->item_compare_numbers) { ! varnumber_T v1 = tv_get_number(tv1); ! varnumber_T v2 = tv_get_number(tv2); return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; } --- 1910,1917 ---- if (sortinfo->item_compare_numbers) { ! varnumber_T v1 = tv_to_number(tv1); ! varnumber_T v2 = tv_to_number(tv2); return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; } *************** *** 2831,2837 **** } 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 // declared. if (!is_new && in_vim9script() && argvars[0].vval.v_dict != NULL) type = argvars[0].vval.v_dict->dv_type; --- 2831,2837 ---- } else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) { ! // 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; *** ../vim-9.0.1395/src/typval.c 2023-03-04 20:47:32.308617862 +0000 --- src/typval.c 2023-03-09 22:02:13.873074418 +0000 *************** *** 188,194 **** } static varnumber_T ! tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool) { varnumber_T n = 0L; --- 188,198 ---- } static varnumber_T ! 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,216 **** emsg(_(e_using_funcref_as_number)); break; case VAR_STRING: ! if (in_vim9script()) { emsg_using_string_as(varp, !want_bool); break; --- 214,220 ---- emsg(_(e_using_funcref_as_number)); break; case VAR_STRING: ! if (vim9_string_error && in_vim9script()) { emsg_using_string_as(varp, !want_bool); break; *************** *** 287,296 **** return tv_get_number_chk(varp, &error); // return 0L on error } varnumber_T tv_get_number_chk(typval_T *varp, int *denote) { ! return tv_get_bool_or_number_chk(varp, denote, FALSE); } /* --- 291,312 ---- 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, TRUE); } /* *************** *** 300,306 **** varnumber_T tv_get_bool(typval_T *varp) { ! return tv_get_bool_or_number_chk(varp, NULL, TRUE); } /* --- 316,322 ---- varnumber_T tv_get_bool(typval_T *varp) { ! return tv_get_bool_or_number_chk(varp, NULL, TRUE, TRUE); } /* *************** *** 310,316 **** varnumber_T tv_get_bool_chk(typval_T *varp, int *denote) { ! return tv_get_bool_or_number_chk(varp, denote, TRUE); } static float_T --- 326,332 ---- varnumber_T tv_get_bool_chk(typval_T *varp, int *denote) { ! return tv_get_bool_or_number_chk(varp, denote, TRUE, TRUE); } static float_T *** ../vim-9.0.1395/src/proto/typval.pro 2023-01-02 20:32:18.425749782 +0000 --- src/proto/typval.pro 2023-03-09 22:02:56.604762446 +0000 *************** *** 5,10 **** --- 5,11 ---- 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); *** ../vim-9.0.1395/src/testdir/test_sort.vim 2022-10-10 22:39:38.203545897 +0100 --- src/testdir/test_sort.vim 2023-03-09 22:04:00.372335382 +0000 *************** *** 58,63 **** --- 58,64 ---- 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 *** ../vim-9.0.1395/src/version.c 2023-03-08 20:35:14.097890706 +0000 --- src/version.c 2023-03-09 22:05:32.319790770 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1396, /**/ -- hundred-and-one symptoms of being an internet addict: 253. You wait for a slow loading web page before going to the toilet. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///