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)
45cf6e910c
This commit is contained in:
Jan Edmund Lazo 2018-06-30 08:16:10 -04:00 committed by Justin M. Keyes
parent d088331ea3
commit 70626e6a1e
3 changed files with 49 additions and 43 deletions

View File

@ -4513,9 +4513,7 @@ eval_index(
item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item); item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item);
} }
tv_clear(rettv); tv_clear(rettv);
rettv->v_type = VAR_LIST; tv_list_set_ret(rettv, l);
rettv->vval.v_list = l;
tv_list_ref(l);
} else { } else {
tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1); tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1);
tv_clear(rettv); tv_clear(rettv);
@ -4899,9 +4897,7 @@ failret:
*arg = skipwhite(*arg + 1); *arg = skipwhite(*arg + 1);
if (evaluate) { if (evaluate) {
rettv->v_type = VAR_LIST; tv_list_set_ret(rettv, l);
rettv->vval.v_list = l;
tv_list_ref(l);
} }
return OK; return OK;
@ -5626,9 +5622,7 @@ failret:
*arg = skipwhite(*arg + 1); *arg = skipwhite(*arg + 1);
if (evaluate) { if (evaluate) {
rettv->v_type = VAR_DICT; tv_dict_set_ret(rettv, d);
rettv->vval.v_dict = d;
++d->dv_refcount;
} }
return OK; return OK;
@ -8225,8 +8219,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
&& argvars[2].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN
&& tv_get_number_chk(&argvars[2], &error) && tv_get_number_chk(&argvars[2], &error)
&& !error) { && !error) {
rettv->v_type = VAR_LIST; tv_list_set_ret(rettv, NULL);
rettv->vval.v_list = NULL;
} }
const char *s = tv_get_string(&argvars[0]); 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); func_ref(rettv->vval.v_string);
} }
} else if (strcmp(what, "dict") == 0) { } else if (strcmp(what, "dict") == 0) {
rettv->v_type = VAR_DICT; tv_dict_set_ret(rettv, pt->pt_dict);
rettv->vval.v_dict = pt->pt_dict;
if (pt->pt_dict != NULL) {
(pt->pt_dict->dv_refcount)++;
}
} else if (strcmp(what, "args") == 0) { } else if (strcmp(what, "args") == 0) {
rettv->v_type = VAR_LIST; rettv->v_type = VAR_LIST;
if (tv_list_alloc_ret(rettv, pt->pt_argc) != NULL) { 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); dict_T *opts = get_winbuf_options(true);
if (opts != NULL) { if (opts != NULL) {
rettv->v_type = VAR_DICT; tv_dict_set_ret(rettv, opts);
rettv->vval.v_dict = opts;
opts->dv_refcount++;
done = true; done = true;
} }
} else if (get_option_tv(&varname, rettv, true) == OK) { } else if (get_option_tv(&varname, rettv, true) == OK) {
@ -10419,9 +10406,7 @@ getwinvar(
dict_T *opts = get_winbuf_options(false); dict_T *opts = get_winbuf_options(false);
if (opts != NULL) { if (opts != NULL) {
rettv->v_type = VAR_DICT; tv_dict_set_ret(rettv, opts);
rettv->vval.v_dict = opts;
opts->dv_refcount++;
done = true; done = true;
} }
} else if (get_option_tv(&varname, rettv, 1) == OK) { } 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 (argvars[2].v_type != VAR_UNKNOWN) {
if (tv_get_number_chk(&argvars[2], &error)) { if (tv_get_number_chk(&argvars[2], &error)) {
rettv->v_type = VAR_LIST; tv_list_set_ret(rettv, NULL);
rettv->vval.v_list = NULL;
} }
if (argvars[3].v_type != VAR_UNKNOWN if (argvars[3].v_type != VAR_UNKNOWN
&& tv_get_number_chk(&argvars[3], &error)) { && 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 (argvars[3].v_type != VAR_UNKNOWN) {
if (tv_get_number_chk(&argvars[3], &error)) { if (tv_get_number_chk(&argvars[3], &error)) {
rettv->v_type = VAR_LIST; tv_list_set_ret(rettv, NULL);
rettv->vval.v_list = NULL;
} }
if (argvars[4].v_type != VAR_UNKNOWN if (argvars[4].v_type != VAR_UNKNOWN
&& tv_get_number_chk(&argvars[4], &error)) { && 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)), } else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
N_("reverse() argument"), TV_TRANSLATE)) { N_("reverse() argument"), TV_TRANSLATE)) {
tv_list_reverse(l); tv_list_reverse(l);
rettv->vval.v_list = l; tv_list_set_ret(rettv, l);
rettv->v_type = VAR_LIST;
tv_list_ref(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)) { if (tv_check_lock(tv_list_locked(l), arg_errmsg, TV_TRANSLATE)) {
goto theend; goto theend;
} }
rettv->vval.v_list = l; tv_list_set_ret(rettv, l);
rettv->v_type = VAR_LIST;
tv_list_ref(l);
len = tv_list_len(l); len = tv_list_len(l);
if (len <= 1) { if (len <= 1) {
@ -16330,8 +16309,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int matchid = 0; int matchid = 0;
char_u str[NUMBUFLEN]; char_u str[NUMBUFLEN];
rettv->v_type = VAR_LIST; tv_list_set_ret(rettv, NULL);
rettv->vval.v_list = NULL;
// -1 on type error (both) // -1 on type error (both)
const linenr_T lnum = tv_get_lnum(argvars); 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) static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{ {
rettv->v_type = VAR_LIST; tv_list_set_ret(rettv, NULL);
rettv->vval.v_list = NULL;
// -1 on type error (both) // -1 on type error (both)
const linenr_T lnum = tv_get_lnum(argvars); const linenr_T lnum = tv_get_lnum(argvars);

View File

@ -1914,10 +1914,8 @@ list_T *tv_list_alloc_ret(typval_T *const ret_tv, const ptrdiff_t len)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
list_T *const l = tv_list_alloc(len); list_T *const l = tv_list_alloc(len);
ret_tv->vval.v_list = l; tv_list_set_ret(ret_tv, l);
ret_tv->v_type = VAR_LIST;
ret_tv->v_lock = VAR_UNLOCKED; ret_tv->v_lock = VAR_UNLOCKED;
tv_list_ref(l);
return l; return l;
} }
@ -1930,10 +1928,8 @@ void tv_dict_alloc_ret(typval_T *const ret_tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
dict_T *const d = tv_dict_alloc(); dict_T *const d = tv_dict_alloc();
ret_tv->vval.v_dict = d; tv_dict_set_ret(ret_tv, d);
ret_tv->v_type = VAR_DICT;
ret_tv->v_lock = VAR_UNLOCKED; ret_tv->v_lock = VAR_UNLOCKED;
d->dv_refcount++;
} }
//{{{3 Clear //{{{3 Clear

View File

@ -413,11 +413,14 @@ static inline void list_log(const list_T *const l,
#define TV_DICT_HI2DI(hi) \ #define TV_DICT_HI2DI(hi) \
((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) ((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 /// Increase reference count for a given list
/// ///
/// Does nothing for NULL lists. /// 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) static inline void tv_list_ref(list_T *const l)
{ {
if (l == NULL) { if (l == NULL) {
@ -426,6 +429,20 @@ static inline void tv_list_ref(list_T *const l)
l->lv_refcount++; 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) static inline VarLockStatus tv_list_locked(const list_T *const l)
REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; 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; 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) static inline long tv_dict_len(const dict_T *const d)
REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;