diff options
author | André Twupack <atwupack@mailbox.org> | 2014-09-05 23:34:51 +0200 |
---|---|---|
committer | André Twupack <atwupack@mailbox.org> | 2014-09-13 19:11:07 +0200 |
commit | 75413496ae9169807e74d711e29a2f0107ceed6d (patch) | |
tree | 0089648859907e3edbaf2181d223eaaaf74208cb /src/nvim/eval.c | |
parent | c68468500f5aac86414a54c753af53e8e3f8b841 (diff) | |
download | rneovim-75413496ae9169807e74d711e29a2f0107ceed6d.tar.gz rneovim-75413496ae9169807e74d711e29a2f0107ceed6d.tar.bz2 rneovim-75413496ae9169807e74d711e29a2f0107ceed6d.zip |
vim-patch:7.4.351
Problem: sort() is not stable.
Solution: When the items are identical, compare the pointers.
https://code.google.com/p/vim/source/detail?r=v7-4-351
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8d06660b1b..d8fd6f95c5 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13366,6 +13366,7 @@ static bool item_compare_numeric; static char_u *item_compare_func; static dict_T *item_compare_selfdict; static int item_compare_func_err; +static bool item_compare_keep_zero; #define ITEM_COMPARE_FAIL 999 /* @@ -13397,6 +13398,13 @@ static int item_compare(const void *s1, const void *s2) n2 = strtod((char *)p2, (char **)&p2); res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1; } + + // When the result would be zero, compare the pointers themselves. Makes + // the sort stable. + if (res == 0 && !item_compare_keep_zero) { + res = s1 > s2 ? 1 : -1; + } + free(tofree1); free(tofree2); return res; @@ -13413,8 +13421,8 @@ static int item_compare2(const void *s1, const void *s2) if (item_compare_func_err) return 0; - /* copy the values. This is needed to be able to set v_lock to VAR_FIXED - * in the copy without changing the original list items. */ + // Copy the values. This is needed to be able to set v_lock to VAR_FIXED + // in the copy without changing the original list items. copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); @@ -13432,6 +13440,13 @@ static int item_compare2(const void *s1, const void *s2) if (item_compare_func_err) res = ITEM_COMPARE_FAIL; /* return value has wrong type */ clear_tv(&rettv); + + // When the result would be zero, compare the pointers themselves. Makes + // the sort stable. + if (res == 0 && !item_compare_keep_zero) { + res = s1 > s2 ? 1 : -1; + } + return res; } @@ -13513,6 +13528,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } item_compare_func_err = FALSE; + item_compare_keep_zero = false; // Test the compare function. if (item_compare_func != NULL && item_compare2(&ptrs[0], &ptrs[1]) == ITEM_COMPARE_FAIL) { @@ -13539,6 +13555,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) // f_uniq(): ptrs will be a stack of items to remove. item_compare_func_err = FALSE; + item_compare_keep_zero = true; item_compare_func_ptr = item_compare_func ? item_compare2 : item_compare; for (li = l->lv_first; li != NULL && li->li_next != NULL; li = li->li_next) { |