diff options
-rw-r--r-- | src/nvim/eval.c | 19 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 7 | ||||
-rw-r--r-- | test/unit/eval/typval_spec.lua | 20 |
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}) |