Skip to content

Commit be19d78

Browse files
committed
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)
1 parent 638388b commit be19d78

File tree

6 files changed

+31
-10
lines changed

6 files changed

+31
-10
lines changed

runtime/doc/builtin.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8641,8 +8641,9 @@ sort({list} [, {how} [, {dict}]]) *sort()* *E702*
86418641

86428642
When {how} is given and it is 'n' then all items will be
86438643
sorted numerical (Implementation detail: this uses the
8644-
strtod() function to parse numbers, Strings, Lists, Dicts and
8645-
Funcrefs will be considered as being 0).
8644+
strtod() function to parse numbers. Strings, Lists, Dicts and
8645+
Funcrefs will be considered as being 0). Note that this won't
8646+
sort a list of strings with numbers!
86468647

86478648
When {how} is given and it is 'N' then all items will be
86488649
sorted numerical. This is like 'n' but a string containing

src/list.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,8 +1910,8 @@ item_compare(const void *s1, const void *s2)
19101910

19111911
if (sortinfo->item_compare_numbers)
19121912
{
1913-
varnumber_T v1 = tv_get_number(tv1);
1914-
varnumber_T v2 = tv_get_number(tv2);
1913+
varnumber_T v1 = tv_to_number(tv1);
1914+
varnumber_T v2 = tv_to_number(tv2);
19151915

19161916
return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
19171917
}
@@ -2831,7 +2831,7 @@ extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new)
28312831
}
28322832
else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
28332833
{
2834-
// Check that extend() does not change the type of the list if it was
2834+
// Check that extend() does not change the type of the dict if it was
28352835
// declared.
28362836
if (!is_new && in_vim9script() && argvars[0].vval.v_dict != NULL)
28372837
type = argvars[0].vval.v_dict->dv_type;

src/proto/typval.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ void free_tv(typval_T *varp);
55
void clear_tv(typval_T *varp);
66
void init_tv(typval_T *varp);
77
varnumber_T tv_get_number(typval_T *varp);
8+
varnumber_T tv_to_number(typval_T *varp);
89
varnumber_T tv_get_number_chk(typval_T *varp, int *denote);
910
varnumber_T tv_get_bool(typval_T *varp);
1011
varnumber_T tv_get_bool_chk(typval_T *varp, int *denote);

src/testdir/test_sort.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ endfunc
5858
func Test_sort_numbers()
5959
call assert_equal([3, 13, 28], sort([13, 28, 3], 'N'))
6060
call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N'))
61+
vim9cmd call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N'))
6162
call assert_equal([3997, 4996], sort([4996, 3997], 'Compare1'))
6263
endfunc
6364

src/typval.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ init_tv(typval_T *varp)
188188
}
189189

190190
static varnumber_T
191-
tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
191+
tv_get_bool_or_number_chk(
192+
typval_T *varp,
193+
int *denote,
194+
int want_bool,
195+
int vim9_string_error) // in Vim9 using a string is an error
192196
{
193197
varnumber_T n = 0L;
194198

@@ -210,7 +214,7 @@ tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
210214
emsg(_(e_using_funcref_as_number));
211215
break;
212216
case VAR_STRING:
213-
if (in_vim9script())
217+
if (vim9_string_error && in_vim9script())
214218
{
215219
emsg_using_string_as(varp, !want_bool);
216220
break;
@@ -287,10 +291,22 @@ tv_get_number(typval_T *varp)
287291
return tv_get_number_chk(varp, &error); // return 0L on error
288292
}
289293

294+
/*
295+
* Like tv_get_numbe() but in Vim9 script do convert a number in a string to a
296+
* number without giving an error.
297+
*/
298+
varnumber_T
299+
tv_to_number(typval_T *varp)
300+
{
301+
int error = FALSE;
302+
303+
return tv_get_bool_or_number_chk(varp, &error, FALSE, FALSE);
304+
}
305+
290306
varnumber_T
291307
tv_get_number_chk(typval_T *varp, int *denote)
292308
{
293-
return tv_get_bool_or_number_chk(varp, denote, FALSE);
309+
return tv_get_bool_or_number_chk(varp, denote, FALSE, TRUE);
294310
}
295311

296312
/*
@@ -300,7 +316,7 @@ tv_get_number_chk(typval_T *varp, int *denote)
300316
varnumber_T
301317
tv_get_bool(typval_T *varp)
302318
{
303-
return tv_get_bool_or_number_chk(varp, NULL, TRUE);
319+
return tv_get_bool_or_number_chk(varp, NULL, TRUE, TRUE);
304320
}
305321

306322
/*
@@ -310,7 +326,7 @@ tv_get_bool(typval_T *varp)
310326
varnumber_T
311327
tv_get_bool_chk(typval_T *varp, int *denote)
312328
{
313-
return tv_get_bool_or_number_chk(varp, denote, TRUE);
329+
return tv_get_bool_or_number_chk(varp, denote, TRUE, TRUE);
314330
}
315331

316332
static float_T

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
1396,
698700
/**/
699701
1395,
700702
/**/

0 commit comments

Comments
 (0)