Merge pull request #5826 from ZyX-I/fix-typval_encode

Refactor eval/typval_encode.h
This commit is contained in:
James McCoy
2017-01-06 21:11:33 -05:00
committed by GitHub
12 changed files with 1534 additions and 806 deletions

View File

@@ -19042,124 +19042,200 @@ void free_tv(typval_T *varp)
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CONV_NIL() \
#define TYPVAL_ENCODE_CONV_NIL(tv) \
do { \
tv->vval.v_special = kSpecialVarFalse; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_BOOL(ignored) \
TYPVAL_ENCODE_CONV_NIL()
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
TYPVAL_ENCODE_CONV_NIL(tv)
#define TYPVAL_ENCODE_CONV_NUMBER(ignored) \
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
do { \
(void)ignored; \
(void)num; \
tv->vval.v_number = 0; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(ignored) \
assert(false)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
#define TYPVAL_ENCODE_CONV_FLOAT(ignored) \
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
do { \
tv->vval.v_float = 0; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_STRING(str, ignored) \
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
xfree(str); \
xfree(buf); \
tv->vval.v_string = NULL; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(ignored1, ignored2)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len)
#define TYPVAL_ENCODE_CONV_EXT_STRING(ignored1, ignored2, ignored3)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
#define TYPVAL_ENCODE_CONV_FUNC(fun) \
static inline int _nothing_conv_func_start(typval_T *const tv,
char_u *const fun)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
{
tv->v_lock = VAR_UNLOCKED;
if (tv->v_type == VAR_PARTIAL) {
partial_T *const pt_ = tv->vval.v_partial;
if (pt_ != NULL && pt_->pt_refcount > 1) {
pt_->pt_refcount--;
tv->vval.v_partial = NULL;
return OK;
}
} else {
func_unref(fun);
if (fun != empty_string) {
xfree(fun);
}
tv->vval.v_string = NULL;
}
return NOTDONE;
}
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
do { \
func_unref(fun); \
if (fun != empty_string) { \
xfree(fun); \
if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
return OK; \
} \
tv->vval.v_string = NULL; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_PARTIAL(pt) \
do { \
partial_unref(pt); \
pt = NULL; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
if (tv->v_type == VAR_PARTIAL) {
partial_T *const pt = tv->vval.v_partial;
if (pt == NULL) {
return;
}
// Dictionary should already be freed by the time.
// If it was not freed then it is a part of the reference cycle.
assert(pt->pt_dict == NULL || pt->pt_dict->dv_copyID == copyID);
pt->pt_dict = NULL;
// As well as all arguments.
pt->pt_argc = 0;
assert(pt->pt_refcount <= 1);
partial_unref(pt);
tv->vval.v_partial = NULL;
assert(tv->v_lock == VAR_UNLOCKED);
}
}
#define TYPVAL_ENCODE_CONV_FUNC_END(tv) _nothing_conv_func_end(tv, copyID)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
do { \
list_unref(tv->vval.v_list); \
tv->vval.v_list = NULL; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
do { \
dict_unref(tv->vval.v_dict); \
tv->vval.v_dict = NULL; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_LIST_START(ignored) \
do { \
if (tv->vval.v_list->lv_refcount > 1) { \
tv->vval.v_list->lv_refcount--; \
tv->vval.v_list = NULL; \
tv->v_lock = VAR_UNLOCKED; \
return OK; \
assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
dict_unref((dict_T *)dict); \
*((dict_T **)&dict) = NULL; \
if (tv != NULL) { \
((typval_T *)tv)->v_lock = VAR_UNLOCKED; \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_LIST_END() \
static inline int _nothing_conv_list_start(typval_T *const tv)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (tv == NULL) {
return NOTDONE;
}
tv->v_lock = VAR_UNLOCKED;
if (tv->vval.v_list->lv_refcount > 1) {
tv->vval.v_list->lv_refcount--;
tv->vval.v_list = NULL;
return OK;
}
return NOTDONE;
}
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
do { \
typval_T *const cur_tv = cur_mpsv->tv; \
assert(cur_tv->v_type == VAR_LIST); \
list_unref(cur_tv->vval.v_list); \
cur_tv->vval.v_list = NULL; \
cur_tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_DICT_START(ignored) \
do { \
if (tv->vval.v_dict->dv_refcount > 1) { \
tv->vval.v_dict->dv_refcount--; \
tv->vval.v_dict = NULL; \
tv->v_lock = VAR_UNLOCKED; \
return OK; \
if (_nothing_conv_list_start(tv) != NOTDONE) { \
goto typval_encode_stop_converting_one_item; \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(ignored1, ignored2)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY()
static inline void _nothing_conv_list_end(typval_T *const tv)
FUNC_ATTR_ALWAYS_INLINE
{
if (tv == NULL) {
return;
}
assert(tv->v_type == VAR_LIST);
list_T *const list = tv->vval.v_list;
list_unref(list);
tv->vval.v_list = NULL;
}
#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_DICT_END() \
static inline int _nothing_conv_dict_start(typval_T *const tv,
dict_T **const dictp,
const void *const nodictvar)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (tv != NULL) {
tv->v_lock = VAR_UNLOCKED;
}
if ((const void *)dictp != nodictvar && (*dictp)->dv_refcount > 1) {
(*dictp)->dv_refcount--;
*dictp = NULL;
return OK;
}
return NOTDONE;
}
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
do { \
typval_T *const cur_tv = cur_mpsv->tv; \
assert(cur_tv->v_type == VAR_DICT); \
dict_unref(cur_tv->vval.v_dict); \
cur_tv->vval.v_dict = NULL; \
cur_tv->v_lock = VAR_UNLOCKED; \
if (_nothing_conv_dict_start(tv, (dict_T **)&dict, \
(void *)&TYPVAL_ENCODE_NODICT_VAR) \
!= NOTDONE) { \
goto typval_encode_stop_converting_one_item; \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_RECURSE(ignored1, ignored2)
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
// nothing_convert_one_value()
// encode_vim_to_nothing()
TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, nothing, void *, ignored)
static inline void _nothing_conv_dict_end(typval_T *const tv,
dict_T **const dictp,
const void *const nodictvar)
FUNC_ATTR_ALWAYS_INLINE
{
if ((const void *)dictp != nodictvar) {
dict_unref(*dictp);
*dictp = NULL;
}
}
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
_nothing_conv_dict_end(tv, (dict_T **)&dict, \
(void *)&TYPVAL_ENCODE_NODICT_VAR)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
#define TYPVAL_ENCODE_SCOPE static
#define TYPVAL_ENCODE_NAME nothing
#define TYPVAL_ENCODE_FIRST_ARG_TYPE const void *const
#define TYPVAL_ENCODE_FIRST_ARG_NAME ignored
#include "nvim/eval/typval_encode.c.h"
#undef TYPVAL_ENCODE_SCOPE
#undef TYPVAL_ENCODE_NAME
#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
#undef TYPVAL_ENCODE_FIRST_ARG_NAME
#undef TYPVAL_ENCODE_ALLOW_SPECIALS
#undef TYPVAL_ENCODE_CONV_NIL
@@ -19170,15 +19246,17 @@ TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, nothing, void *, ignored)
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
#undef TYPVAL_ENCODE_CONV_FUNC
#undef TYPVAL_ENCODE_CONV_PARTIAL
#undef TYPVAL_ENCODE_CONV_FUNC_START
#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
#undef TYPVAL_ENCODE_CONV_FUNC_END
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_DICT_START
#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_DICT_END
@@ -19190,7 +19268,9 @@ TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, nothing, void *, ignored)
void clear_tv(typval_T *varp)
{
if (varp != NULL && varp->v_type != VAR_UNKNOWN) {
encode_vim_to_nothing(varp, varp, "clear_tv argument");
const int evn_ret = encode_vim_to_nothing(varp, varp, "clear_tv argument");
(void)evn_ret;
assert(evn_ret == OK);
}
}