]> granicus.if.org Git - vim/commitdiff
patch 9.0.1396: sort(list, 'N') does not work in Vim9 script context v9.0.1396
authorBram Moolenaar <Bram@vim.org>
Thu, 9 Mar 2023 22:06:49 +0000 (22:06 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 9 Mar 2023 22:06:49 +0000 (22:06 +0000)
Problem:    sort(list, 'N') does not work in Vim9 script context.
Solution:   Convert string to number without giving an error. (closes #12061)

runtime/doc/builtin.txt
src/list.c
src/proto/typval.pro
src/testdir/test_sort.vim
src/typval.c
src/version.c

index a695547eebb9b9ce9d02ee71ccc70f58a9633edd..da2bf32f7d96f69b2366ce9271217520c55f49bd 100644 (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
index ae9e3e957a22900548fe1f5c123da5dfa471de3d..991be8b01fa3935f8806a0dee7c8ef1a9e853f07 100644 (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;
index f3184d0250c8c0b175ff347376ee047c62efd929..8cecdb8d812e716a235baa727c1a69d70806f9ba 100644 (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);
index a2731a800467dabf04b87fadfbbb270758c80b71..14a70cf934addf58a537c6f5958096aa0ba3562d 100644 (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
 
index 10932e5665eccb783bd18321fd518622aaead2df..a760f356bf4e745ac1e0e9646ee73ebfef400eb5 100644 (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
index 82d89c1ce500aeb40bd85af1e0936bdf7ff2b487..24c6fa307edda8237d33bece56c772a4729f3954 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1396,
 /**/
     1395,
 /**/