]> granicus.if.org Git - vim/commitdiff
patch 8.1.0959: sorting large numbers is not tested v8.1.0959
authorBram Moolenaar <Bram@vim.org>
Wed, 20 Feb 2019 21:19:05 +0000 (22:19 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 20 Feb 2019 21:19:05 +0000 (22:19 +0100)
Problem:    Sorting large numbers is not tested and does not work properly.
Solution:   Add test.  Fix comparing lines with and without a number.
            (Dominique Pelle, closes #4017)

src/ex_cmds.c
src/testdir/test_sort.vim
src/version.c

index da10c1291a76c302486a0bf11fa10187ce3d3d82..7682931d86ee6a3252d937de921e13b5cc2426f6 100644 (file)
@@ -296,16 +296,20 @@ static int        sort_abort;     /* flag to indicate if sorting has been interrupted */
 /* Struct to store info to be sorted. */
 typedef struct
 {
-    linenr_T   lnum;                   /* line number */
+    linenr_T   lnum;                   // line number
     union {
        struct
        {
-           varnumber_T start_col_nr;           /* starting column number */
-           varnumber_T end_col_nr;             /* ending column number */
+           varnumber_T start_col_nr;   // starting column number
+           varnumber_T end_col_nr;     // ending column number
        } line;
-       varnumber_T     value;          /* value if sorting by integer */
+       struct
+       {
+           varnumber_T value;          // value if sorting by integer
+           int is_number;              // TRUE when line contains a number
+       } num;
 #ifdef FEAT_FLOAT
-       float_T value_flt;      /* value if sorting by float */
+       float_T value_flt;              // value if sorting by float
 #endif
     } st_u;
 } sorti_T;
@@ -335,11 +339,14 @@ sort_compare(const void *s1, const void *s2)
     if (got_int)
        sort_abort = TRUE;
 
-    /* When sorting numbers "start_col_nr" is the number, not the column
-     * number. */
     if (sort_nr)
-       result = l1.st_u.value == l2.st_u.value ? 0
-                                : l1.st_u.value > l2.st_u.value ? 1 : -1;
+    {
+       if (l1.st_u.num.is_number != l2.st_u.num.is_number)
+           result = l1.st_u.num.is_number - l2.st_u.num.is_number;
+       else
+           result = l1.st_u.num.value == l2.st_u.num.value ? 0
+                            : l1.st_u.num.value > l2.st_u.num.value ? 1 : -1;
+    }
 #ifdef FEAT_FLOAT
     else if (sort_flt)
        result = l1.st_u.value_flt == l2.st_u.value_flt ? 0
@@ -553,11 +560,17 @@ ex_sort(exarg_T *eap)
                if (s > p && s[-1] == '-')
                    --s;  /* include preceding negative sign */
                if (*s == NUL)
-                   /* empty line should sort before any number */
-                   nrs[lnum - eap->line1].st_u.value = -MAXLNUM;
+               {
+                   /* line without number should sort before any number */
+                   nrs[lnum - eap->line1].st_u.num.is_number = FALSE;
+                   nrs[lnum - eap->line1].st_u.num.value = 0;
+               }
                else
+               {
+                   nrs[lnum - eap->line1].st_u.num.is_number = TRUE;
                    vim_str2nr(s, NULL, NULL, sort_what,
-                              &nrs[lnum - eap->line1].st_u.value, NULL, 0);
+                              &nrs[lnum - eap->line1].st_u.num.value, NULL, 0);
+               }
            }
 #ifdef FEAT_FLOAT
            else
index 14d008a17f56fa6532cfc70a22c1654bdbfbbebd..7da82b0185ab7dc77dc068d1baecca2bba95c34f 100644 (file)
@@ -1222,6 +1222,77 @@ func Test_sort_cmd()
   enew!
 endfunc
 
+func Test_sort_large_num()
+  new
+  a
+-2147483648
+-2147483647
+
+-1
+0
+1
+-2147483646
+2147483646
+2147483647
+2147483647
+-2147483648
+abc
+
+.
+  " Numerical sort. Non-numeric lines are ordered before numerical lines.
+  " Ordering of non-numerical is stable.
+  sort n
+  call assert_equal(['',
+  \                  'abc',
+  \                  '',
+  \                  '-2147483648',
+  \                  '-2147483648',
+  \                  '-2147483647',
+  \                  '-2147483646',
+  \                  '-1',
+  \                  '0',
+  \                  '1',
+  \                  '2147483646',
+  \                  '2147483647',
+  \                  '2147483647'], getline(1, '$'))
+  bwipe!
+
+  if has('num64')
+    new
+    a
+-9223372036854775808
+-9223372036854775807
+
+-1
+0
+1
+-9223372036854775806
+9223372036854775806
+9223372036854775807
+9223372036854775807
+-9223372036854775808
+abc
+
+.
+    sort n
+    call assert_equal(['',
+    \                  'abc',
+    \                  '',
+    \                  '-9223372036854775808',
+    \                  '-9223372036854775808',
+    \                  '-9223372036854775807',
+    \                  '-9223372036854775806',
+    \                  '-1',
+    \                  '0',
+    \                  '1',
+    \                  '9223372036854775806',
+    \                  '9223372036854775807',
+    \                  '9223372036854775807'], getline(1, '$'))
+    bwipe!
+  endif
+endfunc
+
+
 func Test_sort_cmd_report()
     enew!
     call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3))
index b2d76b7529ee8df62635df233ba0171c2715b3a1..0d9acf4fd44f054b300b3262b43175cf127b1a3c 100644 (file)
@@ -779,6 +779,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    959,
 /**/
     958,
 /**/