Karsten Hopp b85662
To: vim_dev@googlegroups.com
Karsten Hopp b85662
Subject: Patch 7.4.341
Karsten Hopp b85662
Fcc: outbox
Karsten Hopp b85662
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp b85662
Mime-Version: 1.0
Karsten Hopp b85662
Content-Type: text/plain; charset=UTF-8
Karsten Hopp b85662
Content-Transfer-Encoding: 8bit
Karsten Hopp b85662
------------
Karsten Hopp b85662
Karsten Hopp b85662
Patch 7.4.341
Karsten Hopp b85662
Problem:    sort() doesn't handle numbers well.
Karsten Hopp b85662
Solution:   Add an argument to specify sorting on numbers. (Christian Brabandt)
Karsten Hopp b85662
Files:	    runtime/doc/eval.txt, src/eval.c, src/testdir/test55.in,
Karsten Hopp b85662
	    src/testdir/test55.ok
Karsten Hopp b85662
Karsten Hopp b85662
Karsten Hopp b85662
*** ../vim-7.4.340/runtime/doc/eval.txt	2014-06-25 14:39:35.094348583 +0200
Karsten Hopp b85662
--- runtime/doc/eval.txt	2014-06-25 17:05:50.606680574 +0200
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 5618,5628 ****
Karsten Hopp b85662
  		
Karsten Hopp b85662
  		If you want a list to remain unmodified make a copy first: >
Karsten Hopp b85662
  			:let sortedlist = sort(copy(mylist))
Karsten Hopp b85662
- <		Uses the string representation of each item to sort on.
Karsten Hopp b85662
- 		Numbers sort after Strings, |Lists| after Numbers.
Karsten Hopp b85662
- 		For sorting text in the current buffer use |:sort|.
Karsten Hopp b85662
  
Karsten Hopp b85662
! 		When {func} is given and it is one then case is ignored.
Karsten Hopp b85662
  		When {func} is a |Funcref| or a function name, this function
Karsten Hopp b85662
  		is called to compare items.  The function is invoked with two
Karsten Hopp b85662
  		items as argument and must return zero if they are equal, 1 or
Karsten Hopp b85662
--- 5628,5647 ----
Karsten Hopp b85662
  		
Karsten Hopp b85662
  		If you want a list to remain unmodified make a copy first: >
Karsten Hopp b85662
  			:let sortedlist = sort(copy(mylist))
Karsten Hopp b85662
  
Karsten Hopp b85662
! <		When {func} is omitted, is empty or zero, then sort() uses the
Karsten Hopp b85662
! 		string representation of each item to sort on.  Numbers sort
Karsten Hopp b85662
! 		after Strings, |Lists| after Numbers.  For sorting text in the
Karsten Hopp b85662
! 		current buffer use |:sort|.
Karsten Hopp b85662
! 
Karsten Hopp b85662
! 		When {func} is given and it is is '1' or 'i' then case is
Karsten Hopp b85662
! 		ignored.
Karsten Hopp b85662
! 		
Karsten Hopp b85662
! 		When {func} is given and it is 'n' then all items will be
Karsten Hopp b85662
! 		sorted numerical (Implementation detail: This uses the
Karsten Hopp b85662
! 		strtod() function to parse numbers, Strings, Lists, Dicts and
Karsten Hopp b85662
! 		Funcrefs will be considered as being 0).
Karsten Hopp b85662
! 
Karsten Hopp b85662
  		When {func} is a |Funcref| or a function name, this function
Karsten Hopp b85662
  		is called to compare items.  The function is invoked with two
Karsten Hopp b85662
  		items as argument and must return zero if they are equal, 1 or
Karsten Hopp b85662
*** ../vim-7.4.340/src/eval.c	2014-06-17 17:48:21.776628008 +0200
Karsten Hopp b85662
--- src/eval.c	2014-06-25 17:23:05.466719724 +0200
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 17330,17335 ****
Karsten Hopp b85662
--- 17330,17336 ----
Karsten Hopp b85662
  	item_compare2 __ARGS((const void *s1, const void *s2));
Karsten Hopp b85662
  
Karsten Hopp b85662
  static int	item_compare_ic;
Karsten Hopp b85662
+ static int	item_compare_numeric;
Karsten Hopp b85662
  static char_u	*item_compare_func;
Karsten Hopp b85662
  static dict_T	*item_compare_selfdict;
Karsten Hopp b85662
  static int	item_compare_func_err;
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 17359,17368 ****
Karsten Hopp b85662
  	p1 = (char_u *)"";
Karsten Hopp b85662
      if (p2 == NULL)
Karsten Hopp b85662
  	p2 = (char_u *)"";
Karsten Hopp b85662
!     if (item_compare_ic)
Karsten Hopp b85662
! 	res = STRICMP(p1, p2);
Karsten Hopp b85662
      else
Karsten Hopp b85662
! 	res = STRCMP(p1, p2);
Karsten Hopp b85662
      vim_free(tofree1);
Karsten Hopp b85662
      vim_free(tofree2);
Karsten Hopp b85662
      return res;
Karsten Hopp b85662
--- 17360,17379 ----
Karsten Hopp b85662
  	p1 = (char_u *)"";
Karsten Hopp b85662
      if (p2 == NULL)
Karsten Hopp b85662
  	p2 = (char_u *)"";
Karsten Hopp b85662
!     if (!item_compare_numeric)
Karsten Hopp b85662
!     {
Karsten Hopp b85662
! 	if (item_compare_ic)
Karsten Hopp b85662
! 	    res = STRICMP(p1, p2);
Karsten Hopp b85662
! 	else
Karsten Hopp b85662
! 	    res = STRCMP(p1, p2);
Karsten Hopp b85662
!     }
Karsten Hopp b85662
      else
Karsten Hopp b85662
!     {
Karsten Hopp b85662
! 	double n1, n2;
Karsten Hopp b85662
! 	n1 = strtod((char *)p1, (char **)&p1;;
Karsten Hopp b85662
! 	n2 = strtod((char *)p2, (char **)&p2;;
Karsten Hopp b85662
! 	res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
Karsten Hopp b85662
!     }
Karsten Hopp b85662
      vim_free(tofree1);
Karsten Hopp b85662
      vim_free(tofree2);
Karsten Hopp b85662
      return res;
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 17439,17444 ****
Karsten Hopp b85662
--- 17450,17456 ----
Karsten Hopp b85662
  	    return;	/* short list sorts pretty quickly */
Karsten Hopp b85662
  
Karsten Hopp b85662
  	item_compare_ic = FALSE;
Karsten Hopp b85662
+ 	item_compare_numeric = FALSE;
Karsten Hopp b85662
  	item_compare_func = NULL;
Karsten Hopp b85662
  	item_compare_selfdict = NULL;
Karsten Hopp b85662
  	if (argvars[1].v_type != VAR_UNKNOWN)
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 17457,17462 ****
Karsten Hopp b85662
--- 17469,17487 ----
Karsten Hopp b85662
  		    item_compare_ic = TRUE;
Karsten Hopp b85662
  		else
Karsten Hopp b85662
  		    item_compare_func = get_tv_string(&argvars[1]);
Karsten Hopp b85662
+ 		if (item_compare_func != NULL)
Karsten Hopp b85662
+ 		{
Karsten Hopp b85662
+ 		    if (STRCMP(item_compare_func, "n") == 0)
Karsten Hopp b85662
+ 		    {
Karsten Hopp b85662
+ 			item_compare_func = NULL;
Karsten Hopp b85662
+ 			item_compare_numeric = TRUE;
Karsten Hopp b85662
+ 		    }
Karsten Hopp b85662
+ 		    else if (STRCMP(item_compare_func, "i") == 0)
Karsten Hopp b85662
+ 		    {
Karsten Hopp b85662
+ 			item_compare_func = NULL;
Karsten Hopp b85662
+ 			item_compare_ic = TRUE;
Karsten Hopp b85662
+ 		    }
Karsten Hopp b85662
+ 		}
Karsten Hopp b85662
  	    }
Karsten Hopp b85662
  
Karsten Hopp b85662
  	    if (argvars[2].v_type != VAR_UNKNOWN)
Karsten Hopp b85662
*** ../vim-7.4.340/src/testdir/test55.in	2014-03-25 18:23:27.062087691 +0100
Karsten Hopp b85662
--- src/testdir/test55.in	2014-06-25 17:20:47.006714486 +0200
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 332,337 ****
Karsten Hopp b85662
--- 332,342 ----
Karsten Hopp b85662
  :$put =string(reverse(sort(l)))
Karsten Hopp b85662
  :$put =string(sort(reverse(sort(l))))
Karsten Hopp b85662
  :$put =string(uniq(sort(l)))
Karsten Hopp b85662
+ :let l=[7, 9, 18, 12, 22, 10.0e-16, -1, 0xff, 0, -0, 0.22, 'foo', 'FOOBAR',{}, []]
Karsten Hopp b85662
+ :$put =string(sort(copy(l), 'n'))
Karsten Hopp b85662
+ :$put =string(sort(copy(l), 1))
Karsten Hopp b85662
+ :$put =string(sort(copy(l), 'i'))
Karsten Hopp b85662
+ :$put =string(sort(copy(l)))
Karsten Hopp b85662
  :"
Karsten Hopp b85662
  :" splitting a string to a List
Karsten Hopp b85662
  :$put =string(split('  aa  bb '))
Karsten Hopp b85662
*** ../vim-7.4.340/src/testdir/test55.ok	2014-03-25 18:23:27.062087691 +0100
Karsten Hopp b85662
--- src/testdir/test55.ok	2014-06-25 17:23:31.382720704 +0200
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 101,106 ****
Karsten Hopp b85662
--- 101,110 ----
Karsten Hopp b85662
  [[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo', 'A11', '-0']
Karsten Hopp b85662
  ['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]]
Karsten Hopp b85662
  ['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]]
Karsten Hopp b85662
+ [-1, 0, 0, 'foo', 'FOOBAR', {}, [], 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255]
Karsten Hopp b85662
+ ['foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]
Karsten Hopp b85662
+ ['foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]
Karsten Hopp b85662
+ ['FOOBAR', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]
Karsten Hopp b85662
  ['aa', 'bb']
Karsten Hopp b85662
  ['aa', 'bb']
Karsten Hopp b85662
  ['', 'aa', 'bb', '']
Karsten Hopp b85662
*** ../vim-7.4.340/src/version.c	2014-06-25 15:02:29.250400570 +0200
Karsten Hopp b85662
--- src/version.c	2014-06-25 16:46:45.438637250 +0200
Karsten Hopp b85662
***************
Karsten Hopp b85662
*** 736,737 ****
Karsten Hopp b85662
--- 736,739 ----
Karsten Hopp b85662
  {   /* Add new patch number below this line */
Karsten Hopp b85662
+ /**/
Karsten Hopp b85662
+     341,
Karsten Hopp b85662
  /**/
Karsten Hopp b85662
Karsten Hopp b85662
-- 
Karsten Hopp b85662
We do not stumble over mountains, but over molehills.
Karsten Hopp b85662
				Confucius
Karsten Hopp b85662
Karsten Hopp b85662
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp b85662
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp b85662
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp b85662
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///