0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.0.1396: sort(list, 'N') does not work in Vim9 script context

Problem:    sort(list, 'N') does not work in Vim9 script context.
Solution:   Convert string to number without giving an error. (closes #12061)
This commit is contained in:
Bram Moolenaar
2023-03-09 22:06:49 +00:00
parent 638388b8ef
commit be19d78c3d
6 changed files with 31 additions and 10 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

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