From a25e3d06956f1bc11c68fe60149acce2d8547092 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 20 Feb 2019 22:19:05 +0100 Subject: patch 8.1.0959: sorting large numbers is not tested 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 | 37 ++++++++++++++++-------- src/testdir/test_sort.vim | 71 +++++++++++++++++++++++++++++++++++++++++++++++ src/version.c | 2 ++ 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/src/ex_cmds.c b/src/ex_cmds.c index da10c1291..7682931d8 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -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 diff --git a/src/testdir/test_sort.vim b/src/testdir/test_sort.vim index 14d008a17..7da82b018 100644 --- a/src/testdir/test_sort.vim +++ b/src/testdir/test_sort.vim @@ -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)) diff --git a/src/version.c b/src/version.c index b2d76b752..0d9acf4fd 100644 --- a/src/version.c +++ b/src/version.c @@ -779,6 +779,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 959, /**/ 958, /**/ -- cgit v1.2.1