From 70626e6a1eb9c82a5eb4e3b55abfd474908ef501 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 30 Jun 2018 08:16:10 -0400 Subject: [PATCH] vim-patch:8.0.0593: DRY: setting list/dict return value (#8639) Problem: Duplication of code for adding a list or dict return value. Solution: Add rettv_dict_set() and rettv_list_set(). (Yegappan Lakshmanan) https://github.com/vim/vim/commit/45cf6e910c6d162775ca9d470fac4b6db844001f --- src/nvim/eval.c | 49 +++++++++++------------------------------- src/nvim/eval/typval.c | 8 ++----- src/nvim/eval/typval.h | 35 +++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8d45863d6f..2ea0c0116b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -4513,9 +4513,7 @@ eval_index( item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item); } tv_clear(rettv); - rettv->v_type = VAR_LIST; - rettv->vval.v_list = l; - tv_list_ref(l); + tv_list_set_ret(rettv, l); } else { tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1); tv_clear(rettv); @@ -4899,9 +4897,7 @@ failret: *arg = skipwhite(*arg + 1); if (evaluate) { - rettv->v_type = VAR_LIST; - rettv->vval.v_list = l; - tv_list_ref(l); + tv_list_set_ret(rettv, l); } return OK; @@ -5626,9 +5622,7 @@ failret: *arg = skipwhite(*arg + 1); if (evaluate) { - rettv->v_type = VAR_DICT; - rettv->vval.v_dict = d; - ++d->dv_refcount; + tv_dict_set_ret(rettv, d); } return OK; @@ -8225,8 +8219,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) && argvars[2].v_type != VAR_UNKNOWN && tv_get_number_chk(&argvars[2], &error) && !error) { - rettv->v_type = VAR_LIST; - rettv->vval.v_list = NULL; + tv_list_set_ret(rettv, NULL); } const char *s = tv_get_string(&argvars[0]); @@ -9111,11 +9104,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) func_ref(rettv->vval.v_string); } } else if (strcmp(what, "dict") == 0) { - rettv->v_type = VAR_DICT; - rettv->vval.v_dict = pt->pt_dict; - if (pt->pt_dict != NULL) { - (pt->pt_dict->dv_refcount)++; - } + tv_dict_set_ret(rettv, pt->pt_dict); } else if (strcmp(what, "args") == 0) { rettv->v_type = VAR_LIST; if (tv_list_alloc_ret(rettv, pt->pt_argc) != NULL) { @@ -9366,9 +9355,7 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) dict_T *opts = get_winbuf_options(true); if (opts != NULL) { - rettv->v_type = VAR_DICT; - rettv->vval.v_dict = opts; - opts->dv_refcount++; + tv_dict_set_ret(rettv, opts); done = true; } } else if (get_option_tv(&varname, rettv, true) == OK) { @@ -10419,9 +10406,7 @@ getwinvar( dict_T *opts = get_winbuf_options(false); if (opts != NULL) { - rettv->v_type = VAR_DICT; - rettv->vval.v_dict = opts; - opts->dv_refcount++; + tv_dict_set_ret(rettv, opts); done = true; } } else if (get_option_tv(&varname, rettv, 1) == OK) { @@ -10471,8 +10456,7 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (argvars[2].v_type != VAR_UNKNOWN) { if (tv_get_number_chk(&argvars[2], &error)) { - rettv->v_type = VAR_LIST; - rettv->vval.v_list = NULL; + tv_list_set_ret(rettv, NULL); } if (argvars[3].v_type != VAR_UNKNOWN && tv_get_number_chk(&argvars[3], &error)) { @@ -10520,8 +10504,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[3].v_type != VAR_UNKNOWN) { if (tv_get_number_chk(&argvars[3], &error)) { - rettv->v_type = VAR_LIST; - rettv->vval.v_list = NULL; + tv_list_set_ret(rettv, NULL); } if (argvars[4].v_type != VAR_UNKNOWN && tv_get_number_chk(&argvars[4], &error)) { @@ -13590,9 +13573,7 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)), N_("reverse() argument"), TV_TRANSLATE)) { tv_list_reverse(l); - rettv->vval.v_list = l; - rettv->v_type = VAR_LIST; - tv_list_ref(l); + tv_list_set_ret(rettv, l); } } @@ -15351,9 +15332,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) if (tv_check_lock(tv_list_locked(l), arg_errmsg, TV_TRANSLATE)) { goto theend; } - rettv->vval.v_list = l; - rettv->v_type = VAR_LIST; - tv_list_ref(l); + tv_list_set_ret(rettv, l); len = tv_list_len(l); if (len <= 1) { @@ -16330,8 +16309,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) int matchid = 0; char_u str[NUMBUFLEN]; - rettv->v_type = VAR_LIST; - rettv->vval.v_list = NULL; + tv_list_set_ret(rettv, NULL); // -1 on type error (both) const linenr_T lnum = tv_get_lnum(argvars); @@ -16368,8 +16346,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - rettv->v_type = VAR_LIST; - rettv->vval.v_list = NULL; + tv_list_set_ret(rettv, NULL); // -1 on type error (both) const linenr_T lnum = tv_get_lnum(argvars); diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 7930653be0..b151357196 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1914,10 +1914,8 @@ list_T *tv_list_alloc_ret(typval_T *const ret_tv, const ptrdiff_t len) FUNC_ATTR_NONNULL_ALL { list_T *const l = tv_list_alloc(len); - ret_tv->vval.v_list = l; - ret_tv->v_type = VAR_LIST; + tv_list_set_ret(ret_tv, l); ret_tv->v_lock = VAR_UNLOCKED; - tv_list_ref(l); return l; } @@ -1930,10 +1928,8 @@ void tv_dict_alloc_ret(typval_T *const ret_tv) FUNC_ATTR_NONNULL_ALL { dict_T *const d = tv_dict_alloc(); - ret_tv->vval.v_dict = d; - ret_tv->v_type = VAR_DICT; + tv_dict_set_ret(ret_tv, d); ret_tv->v_lock = VAR_UNLOCKED; - d->dv_refcount++; } //{{{3 Clear diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 33e2aa6b61..664bf7332c 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -413,11 +413,14 @@ static inline void list_log(const list_T *const l, #define TV_DICT_HI2DI(hi) \ ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) +static inline void tv_list_ref(list_T *const l) + REAL_FATTR_ALWAYS_INLINE; + /// Increase reference count for a given list /// /// Does nothing for NULL lists. /// -/// @param[in] l List to modify. +/// @param[in,out] l List to modify. static inline void tv_list_ref(list_T *const l) { if (l == NULL) { @@ -426,6 +429,20 @@ static inline void tv_list_ref(list_T *const l) l->lv_refcount++; } +static inline void tv_list_set_ret(typval_T *const tv, list_T *const l) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1); + +/// Set a list as the return value +/// +/// @param[out] tv Object to receive the list +/// @param[in,out] l List to pass to the object +static inline void tv_list_set_ret(typval_T *const tv, list_T *const l) +{ + tv->v_type = VAR_LIST; + tv->vval.v_list = l; + tv_list_ref(l); +} + static inline VarLockStatus tv_list_locked(const list_T *const l) REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; @@ -588,6 +605,22 @@ static inline listitem_T *tv_list_last(const list_T *const l) return l->lv_last; } +static inline void tv_dict_set_ret(typval_T *const tv, dict_T *const d) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1); + +/// Set a dictionary as the return value +/// +/// @param[out] tv Object to receive the dictionary +/// @param[in,out] d Dictionary to pass to the object +static inline void tv_dict_set_ret(typval_T *const tv, dict_T *const d) +{ + tv->v_type = VAR_DICT; + tv->vval.v_dict = d; + if (d != NULL) { + d->dv_refcount++; + } +} + static inline long tv_dict_len(const dict_T *const d) REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;