Patch 7.4.1143
Problem:    Can't sort on floating point numbers.
Solution:   Add the "f" flag to ":sort".  (Alex Jakushev)  Also add the "f"
            flag to sort().
Files:      runtime/doc/change.txt, src/ex_cmds.c, src/testdir/test_sort.vim,
            src/testdir/test57.in, src/testdir/test57.ok, src/eval.c


*** ../vim-7.4.1142/runtime/doc/change.txt      2016-01-02 17:54:04.407793439 
+0100
--- runtime/doc/change.txt      2016-01-19 22:46:11.700221893 +0100
***************
*** 1713,1719 ****
  found here: |sort()|, |uniq()|.
  
                                                        *:sor* *:sort*
! :[range]sor[t][!] [i][u][r][n][x][o][b] [/{pattern}/]
                        Sort lines in [range].  When no range is given all
                        lines are sorted.
  
--- 1745,1751 ----
  found here: |sort()|, |uniq()|.
  
                                                        *:sor* *:sort*
! :[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/]
                        Sort lines in [range].  When no range is given all
                        lines are sorted.
  
***************
*** 1721,1730 ****
--- 1753,1770 ----
  
                        With [i] case is ignored.
  
+                       Options [n][f][x][o][b] are mutually exclusive.
+ 
                        With [n] sorting is done on the first decimal number
                        in the line (after or inside a {pattern} match).
                        One leading '-' is included in the number.
  
+                       With [f] sorting is done on the Float in the line.
+                       The value of Float is determined similar to passing
+                       the text (after or inside a {pattern} match) to
+                       str2float() function. This option is available only
+                       if Vim was compiled with Floating point support.
+ 
                        With [x] sorting is done on the first hexadecimal
                        number in the line (after or inside a {pattern}
                        match).  A leading "0x" or "0X" is ignored.
***************
*** 1736,1745 ****
                        With [b] sorting is done on the first binary number in
                        the line (after or inside a {pattern} match).
  
!                       With [u] only keep the first of a sequence of
!                       identical lines (ignoring case when [i] is used).
!                       Without this flag, a sequence of identical lines
!                       will be kept in their original order.
                        Note that leading and trailing white space may cause
                        lines to be different.
  
--- 1776,1785 ----
                        With [b] sorting is done on the first binary number in
                        the line (after or inside a {pattern} match).
  
!                       With [u] (u stands for unique) only keep the first of
!                       a sequence of identical lines (ignoring case when [i]
!                       is used).  Without this flag, a sequence of identical
!                       lines will be kept in their original order.
                        Note that leading and trailing white space may cause
                        lines to be different.
  
***************
*** 1780,1787 ****
  quite useless.
  
  The details about sorting depend on the library function used.  There is no
! guarantee that sorting is "stable" or obeys the current locale.  You will have
! to try it out.
  
  The sorting can be interrupted, but if you interrupt it too late in the
  process you may end up with duplicated lines.  This also depends on the system
--- 1820,1827 ----
  quite useless.
  
  The details about sorting depend on the library function used.  There is no
! guarantee that sorting obeys the current locale.  You will have to try it out.
! Vim does do a "stable" sort.
  
  The sorting can be interrupted, but if you interrupt it too late in the
  process you may end up with duplicated lines.  This also depends on the system
*** ../vim-7.4.1142/src/ex_cmds.c       2016-01-18 23:28:44.161810727 +0100
--- src/ex_cmds.c       2016-01-19 23:30:11.579183991 +0100
***************
*** 275,292 ****
  static char_u *sortbuf1;
  static char_u *sortbuf2;
  
! static int    sort_ic;                /* ignore case */
! static int    sort_nr;                /* sort on number */
! static int    sort_rx;                /* sort on regex instead of skipping it 
*/
  
! 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 */
!     long      start_col_nr;           /* starting column number or number */
!     long      end_col_nr;             /* ending column number */
  } sorti_T;
  
  static int
--- 275,304 ----
  static char_u *sortbuf1;
  static char_u *sortbuf2;
  
! static int    sort_ic;        /* ignore case */
! static int    sort_nr;        /* sort on number */
! static int    sort_rx;        /* sort on regex instead of skipping it */
! #ifdef FEAT_FLOAT
! static int    sort_flt;       /* sort on floating number */
! #endif
  
! 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 */
!     union {
!       struct
!       {
!           long        start_col_nr;           /* starting column number */
!           long        end_col_nr;             /* ending column number */
!       } line;
!       long    value;          /* value if sorting by integer */
! #ifdef FEAT_FLOAT
!       float_T value_flt;      /* value if sorting by float */
! #endif
!     } st_u;
  } sorti_T;
  
  static int
***************
*** 319,337 ****
      /* When sorting numbers "start_col_nr" is the number, not the column
       * number. */
      if (sort_nr)
!       result = l1.start_col_nr == l2.start_col_nr ? 0
!                                : l1.start_col_nr > l2.start_col_nr ? 1 : -1;
      else
      {
        /* We need to copy one line into "sortbuf1", because there is no
         * guarantee that the first pointer becomes invalid when obtaining the
         * second one. */
!       STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.start_col_nr,
!                                        l1.end_col_nr - l1.start_col_nr + 1);
!       sortbuf1[l1.end_col_nr - l1.start_col_nr] = 0;
!       STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.start_col_nr,
!                                        l2.end_col_nr - l2.start_col_nr + 1);
!       sortbuf2[l2.end_col_nr - l2.start_col_nr] = 0;
  
        result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
                                                 : STRCMP(sortbuf1, sortbuf2);
--- 331,354 ----
      /* 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;
! #ifdef FEAT_FLOAT
!     else if (sort_flt)
!       result = l1.st_u.value_flt == l2.st_u.value_flt ? 0
!                            : l1.st_u.value_flt > l2.st_u.value_flt ? 1 : -1;
! #endif
      else
      {
        /* We need to copy one line into "sortbuf1", because there is no
         * guarantee that the first pointer becomes invalid when obtaining the
         * second one. */
!       STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr,
!                    l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1);
!       sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = 0;
!       STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr,
!                    l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1);
!       sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = 0;
  
        result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
                                                 : STRCMP(sortbuf1, sortbuf2);
***************
*** 382,387 ****
--- 399,407 ----
        goto sortend;
  
      sort_abort = sort_ic = sort_rx = sort_nr = 0;
+ #ifdef FEAT_FLOAT
+     sort_flt = 0;
+ #endif
  
      for (p = eap->arg; *p != NUL; ++p)
      {
***************
*** 393,401 ****
            sort_rx = TRUE;
        else if (*p == 'n')
        {
!           sort_nr = 2;
            ++format_found;
        }
        else if (*p == 'b')
        {
            sort_what = STR2NR_BIN + STR2NR_FORCE;
--- 413,428 ----
            sort_rx = TRUE;
        else if (*p == 'n')
        {
!           sort_nr = 1;
!           ++format_found;
!       }
! #ifdef FEAT_FLOAT
!       else if (*p == 'f')
!       {
!           sort_flt = 1;
            ++format_found;
        }
+ #endif
        else if (*p == 'b')
        {
            sort_what = STR2NR_BIN + STR2NR_FORCE;
***************
*** 460,466 ****
        goto sortend;
      }
  
!     /* From here on "sort_nr" is used as a flag for any number sorting. */
      sort_nr += sort_what;
  
      /*
--- 487,494 ----
        goto sortend;
      }
  
!     /* From here on "sort_nr" is used as a flag for any integer number
!      * sorting. */
      sort_nr += sort_what;
  
      /*
***************
*** 494,500 ****
            if (regmatch.regprog != NULL)
                end_col = 0;
  
!       if (sort_nr)
        {
            /* Make sure vim_str2nr doesn't read any digits past the end
             * of the match, by temporarily terminating the string there */
--- 522,528 ----
            if (regmatch.regprog != NULL)
                end_col = 0;
  
!       if (sort_nr || sort_flt)
        {
            /* Make sure vim_str2nr doesn't read any digits past the end
             * of the match, by temporarily terminating the string there */
***************
*** 503,529 ****
            *s2 = NUL;
            /* Sorting on number: Store the number itself. */
            p = s + start_col;
!           if (sort_what & STR2NR_HEX)
!               s = skiptohex(p);
!           else if (sort_what & STR2NR_BIN)
!               s = skiptobin(p);
!           else
!               s = skiptodigit(p);
!           if (s > p && s[-1] == '-')
!               --s;  /* include preceding negative sign */
!           if (*s == NUL)
!               /* empty line should sort before any number */
!               nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
            else
!               vim_str2nr(s, NULL, NULL, sort_what,
!                              &nrs[lnum - eap->line1].start_col_nr, NULL, 0);
            *s2 = c;
        }
        else
        {
            /* Store the column to sort at. */
!           nrs[lnum - eap->line1].start_col_nr = start_col;
!           nrs[lnum - eap->line1].end_col_nr = end_col;
        }
  
        nrs[lnum - eap->line1].lnum = lnum;
--- 531,575 ----
            *s2 = NUL;
            /* Sorting on number: Store the number itself. */
            p = s + start_col;
!           if (sort_nr)
!           {
!               if (sort_what & STR2NR_HEX)
!                   s = skiptohex(p);
!               else if (sort_what & STR2NR_BIN)
!                   s = skiptobin(p);
!               else
!                   s = skiptodigit(p);
!               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;
!               else
!                   vim_str2nr(s, NULL, NULL, sort_what,
!                              &nrs[lnum - eap->line1].st_u.value, NULL, 0);
!           }
! #ifdef FEAT_FLOAT
            else
!           {
!               s = skipwhite(p);
!               if (*s == '+')
!                   s = skipwhite(s + 1);
! 
!               if (*s == NUL)
!                   /* empty line should sort before any number */
!                   nrs[lnum - eap->line1].st_u.value_flt = -DBL_MAX;
!               else
!                   nrs[lnum - eap->line1].st_u.value_flt =
!                                                     strtod((char *)s, NULL);
!           }
! #endif
            *s2 = c;
        }
        else
        {
            /* Store the column to sort at. */
!           nrs[lnum - eap->line1].st_u.line.start_col_nr = start_col;
!           nrs[lnum - eap->line1].st_u.line.end_col_nr = end_col;
        }
  
        nrs[lnum - eap->line1].lnum = lnum;
*** ../vim-7.4.1142/src/testdir/test_sort.vim   2015-12-03 16:32:52.724051746 
+0100
--- src/testdir/test_sort.vim   2016-01-19 23:21:27.292957153 +0100
***************
*** 17,19 ****
--- 17,23 ----
    call assert_equal([3, 13, 28], sort([13, 28, 3], 'N'))
    call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N'))
  endfunc
+ 
+ func Test_sort_float()
+   call assert_equal([0.28, 3, 13.5], sort([13.5, 0.28, 3], 'f'))
+ endfunc
*** ../vim-7.4.1142/src/testdir/test57.in       2016-01-02 17:54:04.423793267 
+0100
--- src/testdir/test57.in       2016-01-19 23:25:02.442587528 +0100
***************
*** 32,37 ****
--- 32,38 ----
  :/^t27:/+1,/^t28/-1sort no
  :/^t28:/+1,/^t29/-1sort b
  :/^t29:/+1,/^t30/-1sort b
+ :/^t30:/+1,/^t31/-1sort f
  :/^t01:/,$wq! test.out
  ENDTEST
  
***************
*** 496,504 ****
  b322b
  b321
  b321b
- t28: binary
  
  
  0b111000
  0b101100
  0b101001
--- 497,505 ----
  b322b
  b321
  b321b
  
  
+ t28: binary
  0b111000
  0b101100
  0b101001
***************
*** 513,521 ****
  0b100010
  0b100100
  0b100010
- t29: binary with leading characters
  
  
  0b100010
  0b010000
   0b101001
--- 514,522 ----
  0b100010
  0b100100
  0b100010
  
  
+ t29: binary with leading characters
  0b100010
  0b010000
   0b101001
***************
*** 530,533 ****
  0b101010
  0b000000
  b0b111000
! t30: done
--- 531,545 ----
  0b101010
  0b000000
  b0b111000
! 
! 
! t30: float
! 1.234
! 0.88
! 123.456
! 1.15e-6
! -1.1e3
! -1.01e3
! 
! 
! t31: done
*** ../vim-7.4.1142/src/testdir/test57.ok       2016-01-02 17:54:04.423793267 
+0100
--- src/testdir/test57.ok       2016-01-19 23:26:02.829922562 +0100
***************
*** 453,458 ****
--- 453,460 ----
  b322b
  b321
  b321b
+ 
+ 
  t28: binary
  
  
***************
*** 487,490 ****
  0b101010
  b0b101100
  b0b111000
! t30: done
--- 489,501 ----
  0b101010
  b0b101100
  b0b111000
! t30: float
! 
! 
! -1.1e3
! -1.01e3
! 1.15e-6
! 0.88
! 1.234
! 123.456
! t31: done
*** ../vim-7.4.1142/src/eval.c  2016-01-19 20:51:27.743756709 +0100
--- src/eval.c  2016-01-19 23:29:31.387626413 +0100
***************
*** 809,814 ****
--- 809,817 ----
  static typval_T *alloc_string_tv __ARGS((char_u *string));
  static void init_tv __ARGS((typval_T *varp));
  static long get_tv_number __ARGS((typval_T *varp));
+ #ifdef FEAT_FLOAT
+ static float_T get_tv_float(typval_T *varp);
+ #endif
  static linenr_T get_tv_lnum __ARGS((typval_T *argvars));
  static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf));
  static char_u *get_tv_string __ARGS((typval_T *varp));
***************
*** 18143,18148 ****
--- 18146,18154 ----
  static int    item_compare_ic;
  static int    item_compare_numeric;
  static int    item_compare_numbers;
+ #ifdef FEAT_FLOAT
+ static int    item_compare_float;
+ #endif
  static char_u *item_compare_func;
  static dict_T *item_compare_selfdict;
  static int    item_compare_func_err;
***************
*** 18182,18187 ****
--- 18188,18203 ----
        return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
      }
  
+ #ifdef FEAT_FLOAT
+     if (item_compare_float)
+     {
+       float_T v1 = get_tv_float(tv1);
+       float_T v2 = get_tv_float(tv2);
+ 
+       return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+     }
+ #endif
+ 
      /* tv2string() puts quotes around a string and allocates memory.  Don't do
       * that for string variables. Use a single quote when comparing with a
       * non-string to do what the docs promise. */
***************
*** 18316,18321 ****
--- 18332,18340 ----
        item_compare_ic = FALSE;
        item_compare_numeric = FALSE;
        item_compare_numbers = FALSE;
+ #ifdef FEAT_FLOAT
+       item_compare_float = FALSE;
+ #endif
        item_compare_func = NULL;
        item_compare_selfdict = NULL;
        if (argvars[1].v_type != VAR_UNKNOWN)
***************
*** 18346,18351 ****
--- 18365,18377 ----
                        item_compare_func = NULL;
                        item_compare_numbers = TRUE;
                    }
+ #ifdef FEAT_FLOAT
+                   else if (STRCMP(item_compare_func, "f") == 0)
+                   {
+                       item_compare_func = NULL;
+                       item_compare_float = TRUE;
+                   }
+ #endif
                    else if (STRCMP(item_compare_func, "i") == 0)
                    {
                        item_compare_func = NULL;
***************
*** 21613,21618 ****
--- 21639,21678 ----
      return n;
  }
  
+ #ifdef FEAT_FLOAT
+     static float_T
+ get_tv_float(varp)
+     typval_T  *varp;
+ {
+     switch (varp->v_type)
+     {
+       case VAR_NUMBER:
+           return (float_T)(varp->vval.v_number);
+ #ifdef FEAT_FLOAT
+       case VAR_FLOAT:
+           return varp->vval.v_float;
+           break;
+ #endif
+       case VAR_FUNC:
+           EMSG(_("E891: Using a Funcref as a Float"));
+           break;
+       case VAR_STRING:
+           EMSG(_("E892: Using a String as a Float"));
+           break;
+       case VAR_LIST:
+           EMSG(_("E893: Using a List as a Float"));
+           break;
+       case VAR_DICT:
+           EMSG(_("E894: Using a Dictionary as a Float"));
+           break;
+       default:
+           EMSG2(_(e_intern2), "get_tv_float()");
+           break;
+     }
+     return 0;
+ }
+ #endif
+ 
  /*
   * Get the lnum from the first argument.
   * Also accepts ".", "$", etc., but that only works for the current buffer.
*** ../vim-7.4.1142/src/version.c       2016-01-19 22:28:54.615592984 +0100
--- src/version.c       2016-01-19 22:47:19.119483218 +0100
***************
*** 743,744 ****
--- 743,746 ----
  {   /* Add new patch number below this line */
+ /**/
+     1143,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
12. You turn off your modem and get this awful empty feeling, like you just
    pulled the plug on a loved one.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui