mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
updated for version 7.4.218
Problem: It's not easy to remove duplicates from a list. Solution: Add the uniq() function. (LCD)
This commit is contained in:
109
src/eval.c
109
src/eval.c
@@ -744,6 +744,7 @@ static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_type __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_undofile __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_undotree __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_uniq __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_values __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
@@ -8150,6 +8151,7 @@ static struct fst
|
||||
{"type", 1, 1, f_type},
|
||||
{"undofile", 1, 1, f_undofile},
|
||||
{"undotree", 0, 0, f_undotree},
|
||||
{"uniq", 1, 3, f_uniq},
|
||||
{"values", 1, 1, f_values},
|
||||
{"virtcol", 1, 1, f_virtcol},
|
||||
{"visualmode", 0, 1, f_visualmode},
|
||||
@@ -17023,10 +17025,11 @@ static int item_compare_ic;
|
||||
static char_u *item_compare_func;
|
||||
static dict_T *item_compare_selfdict;
|
||||
static int item_compare_func_err;
|
||||
static void do_sort_uniq __ARGS((typval_T *argvars, typval_T *rettv, int sort));
|
||||
#define ITEM_COMPARE_FAIL 999
|
||||
|
||||
/*
|
||||
* Compare functions for f_sort() below.
|
||||
* Compare functions for f_sort() and f_uniq() below.
|
||||
*/
|
||||
static int
|
||||
#ifdef __BORLANDC__
|
||||
@@ -17100,9 +17103,10 @@ item_compare2(s1, s2)
|
||||
* "sort({list})" function
|
||||
*/
|
||||
static void
|
||||
f_sort(argvars, rettv)
|
||||
do_sort_uniq(argvars, rettv, sort)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
int sort;
|
||||
{
|
||||
list_T *l;
|
||||
listitem_T *li;
|
||||
@@ -17111,12 +17115,12 @@ f_sort(argvars, rettv)
|
||||
long i;
|
||||
|
||||
if (argvars[0].v_type != VAR_LIST)
|
||||
EMSG2(_(e_listarg), "sort()");
|
||||
EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
|
||||
else
|
||||
{
|
||||
l = argvars[0].vval.v_list;
|
||||
if (l == NULL || tv_check_lock(l->lv_lock,
|
||||
(char_u *)_("sort() argument")))
|
||||
(char_u *)(sort ? _("sort() argument") : _("uniq() argument"))))
|
||||
return;
|
||||
rettv->vval.v_list = l;
|
||||
rettv->v_type = VAR_LIST;
|
||||
@@ -17163,29 +17167,72 @@ f_sort(argvars, rettv)
|
||||
ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
|
||||
if (ptrs == NULL)
|
||||
return;
|
||||
i = 0;
|
||||
for (li = l->lv_first; li != NULL; li = li->li_next)
|
||||
ptrs[i++] = li;
|
||||
|
||||
item_compare_func_err = FALSE;
|
||||
/* test the compare function */
|
||||
if (item_compare_func != NULL
|
||||
&& item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
|
||||
i = 0;
|
||||
if (sort)
|
||||
{
|
||||
/* sort(): ptrs will be the list to sort */
|
||||
for (li = l->lv_first; li != NULL; li = li->li_next)
|
||||
ptrs[i++] = li;
|
||||
|
||||
item_compare_func_err = FALSE;
|
||||
/* test the compare function */
|
||||
if (item_compare_func != NULL
|
||||
&& item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
|
||||
== ITEM_COMPARE_FAIL)
|
||||
EMSG(_("E702: Sort compare function failed"));
|
||||
EMSG(_("E702: Sort compare function failed"));
|
||||
else
|
||||
{
|
||||
/* Sort the array with item pointers. */
|
||||
qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
|
||||
item_compare_func == NULL ? item_compare : item_compare2);
|
||||
|
||||
if (!item_compare_func_err)
|
||||
{
|
||||
/* Clear the List and append the items in sorted order. */
|
||||
l->lv_first = l->lv_last = l->lv_idx_item = NULL;
|
||||
l->lv_len = 0;
|
||||
for (i = 0; i < len; ++i)
|
||||
list_append(l, ptrs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Sort the array with item pointers. */
|
||||
qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
|
||||
item_compare_func == NULL ? item_compare : item_compare2);
|
||||
int (*item_compare_func_ptr)__ARGS((const void *, const void *));
|
||||
|
||||
/* f_uniq(): ptrs will be a stack of items to remove */
|
||||
item_compare_func_err = FALSE;
|
||||
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)
|
||||
{
|
||||
if (item_compare_func_ptr((void *)&li, (void *)&li->li_next)
|
||||
== 0)
|
||||
ptrs[i++] = li;
|
||||
if (item_compare_func_err)
|
||||
{
|
||||
EMSG(_("E882: Uniq compare function failed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!item_compare_func_err)
|
||||
{
|
||||
/* Clear the List and append the items in the sorted order. */
|
||||
l->lv_first = l->lv_last = l->lv_idx_item = NULL;
|
||||
l->lv_len = 0;
|
||||
for (i = 0; i < len; ++i)
|
||||
list_append(l, ptrs[i]);
|
||||
while (--i >= 0)
|
||||
{
|
||||
li = ptrs[i]->li_next;
|
||||
ptrs[i]->li_next = li->li_next;
|
||||
if (li->li_next != NULL)
|
||||
li->li_next->li_prev = ptrs[i];
|
||||
else
|
||||
l->lv_last = ptrs[i];
|
||||
list_fix_watch(l, li);
|
||||
listitem_free(li);
|
||||
l->lv_len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17193,6 +17240,28 @@ f_sort(argvars, rettv)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "sort({list})" function
|
||||
*/
|
||||
static void
|
||||
f_sort(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
do_sort_uniq(argvars, rettv, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* "uniq({list})" function
|
||||
*/
|
||||
static void
|
||||
f_uniq(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
do_sort_uniq(argvars, rettv, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* "soundfold({word})" function
|
||||
*/
|
||||
|
Reference in New Issue
Block a user