aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/eval.c19
-rw-r--r--src/nvim/eval/typval.c7
-rw-r--r--test/unit/eval/typval_spec.lua20
3 files changed, 24 insertions, 22 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index fac15770a6..0080eded98 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -2904,9 +2904,7 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit)
// Delete a range of List items.
while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
- li = TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li);
- tv_list_item_remove(lp->ll_list, lp->ll_li);
- lp->ll_li = li;
+ lp->ll_li = tv_list_item_remove(lp->ll_list, lp->ll_li);
lp->ll_n1++;
}
} else {
@@ -8467,7 +8465,6 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
static void filter_map(typval_T *argvars, typval_T *rettv, int map)
{
typval_T *expr;
- listitem_T *li, *nli;
list_T *l = NULL;
dictitem_T *di;
hashtab_T *ht;
@@ -8551,20 +8548,21 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
} else {
vimvars[VV_KEY].vv_type = VAR_NUMBER;
- for (li = tv_list_first(l); li != NULL; li = nli) {
+ for (listitem_T *li = tv_list_first(l); li != NULL;) {
if (map
&& tv_check_lock(TV_LIST_ITEM_TV(li)->v_lock, arg_errmsg,
TV_TRANSLATE)) {
break;
}
- nli = TV_LIST_ITEM_NEXT(l, li);
vimvars[VV_KEY].vv_nr = idx;
if (filter_map_one(TV_LIST_ITEM_TV(li), expr, map, &rem) == FAIL
|| did_emsg) {
break;
}
if (!map && rem) {
- tv_list_item_remove(l, li);
+ li = tv_list_item_remove(l, li);
+ } else {
+ li = TV_LIST_ITEM_NEXT(l, li);
}
idx++;
}
@@ -15440,18 +15438,17 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
int idx = 0;
for (listitem_T *li = TV_LIST_ITEM_NEXT(l, tv_list_first(l))
- ; li != NULL
- ; li = TV_LIST_ITEM_NEXT(l, li)) {
+ ; li != NULL;) {
listitem_T *const prev_li = TV_LIST_ITEM_PREV(l, li);
if (item_compare_func_ptr(&prev_li, &li) == 0) {
if (info.item_compare_func_err) {
EMSG(_("E882: Uniq compare function failed"));
break;
}
- tv_list_item_remove(l, li);
- li = tv_list_find(l, idx);
+ li = tv_list_item_remove(l, li);
} else {
idx++;
+ li = TV_LIST_ITEM_NEXT(l, li);
}
}
}
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index a49c34e957..4ebe12104f 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -64,12 +64,17 @@ static listitem_T *tv_list_item_alloc(void)
///
/// @param[out] l List to remove item from.
/// @param[in,out] item Item to remove.
-void tv_list_item_remove(list_T *const l, listitem_T *const item)
+///
+/// @return Pointer to the list item just after removed one, NULL if removed
+/// item was the last one.
+listitem_T *tv_list_item_remove(list_T *const l, listitem_T *const item)
FUNC_ATTR_NONNULL_ALL
{
+ listitem_T *const next_item = TV_LIST_ITEM_NEXT(l, item);
tv_list_remove_items(l, item, item);
tv_clear(TV_LIST_ITEM_TV(item));
xfree(item);
+ return next_item;
}
//{{{2 List watchers
diff --git a/test/unit/eval/typval_spec.lua b/test/unit/eval/typval_spec.lua
index 0536839b71..35b5596c63 100644
--- a/test/unit/eval/typval_spec.lua
+++ b/test/unit/eval/typval_spec.lua
@@ -138,19 +138,19 @@ describe('typval.c', function()
a.li(lis[7]),
})
- lib.tv_list_item_remove(l, lis[1])
+ eq(lis[2], lib.tv_list_item_remove(l, lis[1]))
alloc_log:check({
a.freed(table.remove(lis, 1)),
})
eq(lis, list_items(l))
- lib.tv_list_item_remove(l, lis[6])
+ eq(lis[7], lib.tv_list_item_remove(l, lis[6]))
alloc_log:check({
a.freed(table.remove(lis)),
})
eq(lis, list_items(l))
- lib.tv_list_item_remove(l, lis[3])
+ eq(lis[4], lib.tv_list_item_remove(l, lis[3]))
alloc_log:check({
a.freed(table.remove(lis, 3)),
})
@@ -174,21 +174,21 @@ describe('typval.c', function()
local strings = map(function(li) return li.li_tv.vval.v_string end,
lis)
- lib.tv_list_item_remove(l, lis[1])
+ eq(lis[2], lib.tv_list_item_remove(l, lis[1]))
alloc_log:check({
a.freed(table.remove(strings, 1)),
a.freed(table.remove(lis, 1)),
})
eq(lis, list_items(l))
- lib.tv_list_item_remove(l, lis[2])
+ eq(lis[3], lib.tv_list_item_remove(l, lis[2]))
alloc_log:check({
a.freed(table.remove(strings, 2)),
a.freed(table.remove(lis, 2)),
})
eq(lis, list_items(l))
- lib.tv_list_item_remove(l, lis[2])
+ eq(nil, lib.tv_list_item_remove(l, lis[2]))
alloc_log:check({
a.freed(table.remove(strings, 2)),
a.freed(table.remove(lis, 2)),
@@ -216,19 +216,19 @@ describe('typval.c', function()
a.li(lis[7]),
})
- lib.tv_list_item_remove(l, lis[4])
+ eq(lis[5], lib.tv_list_item_remove(l, lis[4]))
alloc_log:check({a.freed(lis[4])})
eq({lis[1], lis[5], lis[7]}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item})
- lib.tv_list_item_remove(l, lis[2])
+ eq(lis[3], lib.tv_list_item_remove(l, lis[2]))
alloc_log:check({a.freed(lis[2])})
eq({lis[1], lis[5], lis[7]}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item})
- lib.tv_list_item_remove(l, lis[7])
+ eq(nil, lib.tv_list_item_remove(l, lis[7]))
alloc_log:check({a.freed(lis[7])})
eq({lis[1], lis[5], nil}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item == nil and nil})
- lib.tv_list_item_remove(l, lis[1])
+ eq(lis[3], lib.tv_list_item_remove(l, lis[1]))
alloc_log:check({a.freed(lis[1])})
eq({lis[3], lis[5], nil}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item == nil and nil})