eval/typval_encode: Refactor arguments to argument macroses

Fixed local test failures somewhere in process.
This commit is contained in:
ZyX
2017-01-03 06:35:32 +03:00
parent 5ba24318e2
commit ff8944105d
5 changed files with 317 additions and 227 deletions

View File

@@ -326,21 +326,21 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CONV_NIL() \
#define TYPVAL_ENCODE_CONV_NIL(tv) \
kv_push(edata->stack, NIL)
#define TYPVAL_ENCODE_CONV_BOOL(num) \
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
kv_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
#define TYPVAL_ENCODE_CONV_NUMBER(num) \
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
kv_push(edata->stack, INTEGER_OBJ((Integer)(num)))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
kv_push(edata->stack, FLOATING_OBJ((Float)(flt)))
#define TYPVAL_ENCODE_CONV_STRING(str, len) \
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
do { \
const size_t len_ = (size_t)(len); \
const char *const str_ = (const char *)(str); \
@@ -353,20 +353,20 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(str, len, type) \
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
TYPVAL_ENCODE_CONV_NIL()
#define TYPVAL_ENCODE_CONV_FUNC_START(fun, is_partial, pt) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
TYPVAL_ENCODE_CONV_NIL()
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(len)
#define TYPVAL_ENCODE_CONV_FUNC_END()
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
kv_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv) \
kv_push(edata->stack, \
DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
@@ -381,7 +381,7 @@ static inline void typval_encode_list_start(EncodedData *const edata,
})));
}
#define TYPVAL_ENCODE_CONV_LIST_START(len) \
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
typval_encode_list_start(edata, (size_t)(len))
static inline void typval_encode_between_list_items(EncodedData *const edata)
@@ -394,7 +394,7 @@ static inline void typval_encode_between_list_items(EncodedData *const edata)
list->data.array.items[list->data.array.size++] = item;
}
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS() \
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
typval_encode_between_list_items(edata)
static inline void typval_encode_list_end(EncodedData *const edata)
@@ -407,7 +407,7 @@ static inline void typval_encode_list_end(EncodedData *const edata)
#endif
}
#define TYPVAL_ENCODE_CONV_LIST_END() \
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
typval_encode_list_end(edata)
static inline void typval_encode_dict_start(EncodedData *const edata,
@@ -421,10 +421,10 @@ static inline void typval_encode_dict_start(EncodedData *const edata,
})));
}
#define TYPVAL_ENCODE_CONV_DICT_START(len) \
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
typval_encode_dict_start(edata, (size_t)(len))
#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
static inline void typval_encode_after_key(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -443,7 +443,7 @@ static inline void typval_encode_after_key(EncodedData *const edata)
}
}
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY() \
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
typval_encode_after_key(edata)
static inline void typval_encode_between_dict_items(EncodedData *const edata)
@@ -456,7 +456,7 @@ static inline void typval_encode_between_dict_items(EncodedData *const edata)
dict->data.dictionary.items[dict->data.dictionary.size++].value = val;
}
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS() \
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
typval_encode_between_dict_items(edata)
static inline void typval_encode_dict_end(EncodedData *const edata)
@@ -469,7 +469,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
#endif
}
#define TYPVAL_ENCODE_CONV_DICT_END() \
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
typval_encode_dict_end(edata)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
@@ -506,7 +506,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
#undef TYPVAL_ENCODE_CONV_DICT_END
#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_RECURSE

View File

@@ -19034,147 +19034,185 @@ 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_START(fun, is_partial, pt) \
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 { \
partial_T *const pt_ = (pt); \
tv->v_lock = VAR_UNLOCKED; \
if (is_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; \
if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
return OK; \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(len)
#define TYPVAL_ENCODE_CONV_FUNC_END() \
do { \
assert(cur_mpsv != NULL || tv->v_type == VAR_FUNC); \
if (cur_mpsv != NULL && cur_mpsv->type == kMPConvPartial) { \
typval_T *const cur_tv = cur_mpsv->tv; \
partial_T *const pt = cur_mpsv->data.p.pt; \
partial_unref(pt); \
if (cur_tv != NULL) { \
cur_tv->vval.v_partial = NULL; \
cur_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)
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;
}
// Dictionaly should already be freed by the time.
assert(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)
#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) \
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) \
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 { \
tv->v_lock = VAR_UNLOCKED; \
if (tv->vval.v_list->lv_refcount > 1) { \
tv->vval.v_list->lv_refcount--; \
tv->vval.v_list = NULL; \
if (_nothing_conv_list_start(tv) != NOTDONE) { \
return OK; \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
#define TYPVAL_ENCODE_CONV_LIST_END() \
do { \
if (cur_mpsv->type == kMPConvPartialList) { \
break; \
} \
typval_T *const cur_tv = cur_mpsv->tv; \
list_T *const list = cur_mpsv->data.l.list; \
list_unref(list); \
if (cur_tv != NULL) { \
assert(list == cur_tv->vval.v_list); \
assert(cur_tv->v_type == VAR_LIST); \
cur_tv->vval.v_list = NULL; \
} \
} while (0)
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_START(ignored) \
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 { \
tv->v_lock = VAR_UNLOCKED; \
if (tv->vval.v_dict->dv_refcount > 1) { \
tv->vval.v_dict->dv_refcount--; \
tv->vval.v_dict = NULL; \
if (_nothing_conv_dict_start(tv, (dict_T **)&dict, \
(void *)&TYPVAL_ENCODE_NODICT_VAR) \
!= NOTDONE) { \
return OK; \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(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)
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY()
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_DICT_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_DICT_END() \
do { \
typval_T *const cur_tv = cur_mpsv->tv; \
dict_T *const dict = cur_mpsv->data.d.dict; \
dict_unref(cur_tv->vval.v_dict); \
if (cur_tv != NULL) { \
assert(dict == cur_tv->vval.v_dict); \
assert(cur_tv->v_type == VAR_DICT); \
cur_tv->vval.v_dict = NULL; \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_RECURSE(ignored1, ignored2)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
#define TYPVAL_ENCODE_SCOPE static
#define TYPVAL_ENCODE_NAME nothing
@@ -19207,7 +19245,7 @@ void free_tv(typval_T *varp)
#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

View File

@@ -280,7 +280,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
: OK);
}
#define TYPVAL_ENCODE_CONV_STRING(buf, len) \
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
const char *const buf_ = (const char *) buf; \
if (buf == NULL) { \
@@ -299,19 +299,19 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
} \
} while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(buf, len) \
TYPVAL_ENCODE_CONV_STRING(buf, len)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
TYPVAL_ENCODE_CONV_STRING(tv, buf, len)
#define TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
#define TYPVAL_ENCODE_CONV_NUMBER(num) \
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
do { \
char numbuf[NUMBUFLEN]; \
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t) (num)); \
ga_concat(gap, numbuf); \
} while (0)
#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
do { \
const float_T flt_ = (flt); \
switch (fpclassify(flt_)) { \
@@ -334,65 +334,65 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
} \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_START(fun, is_partial, pt) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
do { \
ga_concat(gap, "function("); \
TYPVAL_ENCODE_CONV_STRING(fun, STRLEN(fun)); \
TYPVAL_ENCODE_CONV_STRING(tv, fun, STRLEN(fun)); \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(len) \
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len) \
do { \
if (len != 0) { \
ga_concat(gap, ", "); \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(len) \
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len) \
do { \
if ((ptrdiff_t)len != -1) { \
ga_concat(gap, ", "); \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_END() \
#define TYPVAL_ENCODE_CONV_FUNC_END(tv) \
ga_append(gap, ')')
#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
ga_concat(gap, "[]")
#define TYPVAL_ENCODE_CONV_LIST_START(len) \
#define TYPVAL_ENCODE_CONV_LIST_START(tv, dict) \
ga_append(gap, '[')
#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv) \
ga_concat(gap, "{}")
#define TYPVAL_ENCODE_CONV_NIL() \
#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "v:null")
#define TYPVAL_ENCODE_CONV_BOOL(num) \
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
ga_concat(gap, ((num)? "v:true": "v:false"))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(num)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
#define TYPVAL_ENCODE_CONV_DICT_START(len) \
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
ga_append(gap, '{')
#define TYPVAL_ENCODE_CONV_DICT_END() \
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
ga_append(gap, '}')
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY() \
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
ga_concat(gap, ": ")
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS() \
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
ga_concat(gap, ", ")
#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, key)
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key)
#define TYPVAL_ENCODE_CONV_LIST_END() \
#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
ga_append(gap, ']')
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS() \
TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, NULL)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
do { \
@@ -493,15 +493,15 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
#undef TYPVAL_ENCODE_CONV_NIL
#define TYPVAL_ENCODE_CONV_NIL() \
#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "null")
#undef TYPVAL_ENCODE_CONV_BOOL
#define TYPVAL_ENCODE_CONV_BOOL(num) \
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
ga_concat(gap, ((num)? "true": "false"))
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(num) \
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
do { \
char numbuf[NUMBUFLEN]; \
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRIu64, (num)); \
@@ -509,7 +509,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
} while (0)
#undef TYPVAL_ENCODE_CONV_FLOAT
#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
do { \
const float_T flt_ = (flt); \
switch (fpclassify(flt_)) { \
@@ -698,7 +698,7 @@ static inline int convert_to_json_string(garray_T *const gap,
}
#undef TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_STRING(buf, len) \
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
if (convert_to_json_string(gap, (const char *) (buf), (len)) != OK) { \
return FAIL; \
@@ -706,7 +706,7 @@ static inline int convert_to_json_string(garray_T *const gap,
} while (0)
#undef TYPVAL_ENCODE_CONV_EXT_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type) \
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
do { \
xfree(buf); \
EMSG(_("E474: Unable to convert EXT string to JSON")); \
@@ -714,7 +714,7 @@ static inline int convert_to_json_string(garray_T *const gap,
} while (0)
#undef TYPVAL_ENCODE_CONV_FUNC_START
#define TYPVAL_ENCODE_CONV_FUNC_START(fun, is_partial, pt) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
return conv_error(_("E474: Error while dumping %s, %s: " \
"attempt to dump function reference"), \
mpstack, objname)
@@ -757,8 +757,8 @@ bool encode_check_json_key(const typval_T *const tv)
return true;
}
#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, key) \
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key) \
do { \
if (!encode_check_json_key(&key)) { \
EMSG(_("E474: Invalid key in special dictionary")); \
@@ -797,7 +797,7 @@ bool encode_check_json_key(const typval_T *const tv)
#undef TYPVAL_ENCODE_CONV_DICT_END
#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_RECURSE
@@ -875,7 +875,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
return (char *) ga.ga_data;
}
#define TYPVAL_ENCODE_CONV_STRING(buf, len) \
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
if (buf == NULL) { \
msgpack_pack_bin(packer, 0); \
@@ -886,7 +886,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
} \
} while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(buf, len) \
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
do { \
if (buf == NULL) { \
msgpack_pack_str(packer, 0); \
@@ -897,7 +897,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
} \
} while (0)
#define TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type) \
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
do { \
if (buf == NULL) { \
msgpack_pack_ext(packer, 0, (int8_t) type); \
@@ -908,34 +908,34 @@ char *encode_tv2json(typval_T *tv, size_t *len)
} \
} while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(num) \
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
msgpack_pack_int64(packer, (int64_t) (num))
#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
msgpack_pack_double(packer, (double) (flt))
#define TYPVAL_ENCODE_CONV_FUNC_START(fun, is_partial, pt) \
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
return conv_error(_("E5004: Error while dumping %s, %s: " \
"attempt to dump function reference"), \
mpstack, objname)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(len)
#define TYPVAL_ENCODE_CONV_FUNC_END()
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
msgpack_pack_array(packer, 0)
#define TYPVAL_ENCODE_CONV_LIST_START(len) \
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
msgpack_pack_array(packer, (size_t) (len))
#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv) \
msgpack_pack_map(packer, 0)
#define TYPVAL_ENCODE_CONV_NIL() \
#define TYPVAL_ENCODE_CONV_NIL(tv) \
msgpack_pack_nil(packer)
#define TYPVAL_ENCODE_CONV_BOOL(num) \
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
do { \
if ((num)) { \
msgpack_pack_true(packer); \
@@ -944,23 +944,23 @@ char *encode_tv2json(typval_T *tv, size_t *len)
} \
} while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(num) \
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
msgpack_pack_uint64(packer, (num))
#define TYPVAL_ENCODE_CONV_DICT_START(len) \
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
msgpack_pack_map(packer, (size_t) (len))
#define TYPVAL_ENCODE_CONV_DICT_END()
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY()
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, key)
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key)
#define TYPVAL_ENCODE_CONV_LIST_END()
#define TYPVAL_ENCODE_CONV_LIST_END(tv)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
return conv_error(_("E5005: Unable to dump %s: " \
@@ -1000,7 +1000,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#undef TYPVAL_ENCODE_CONV_DICT_END
#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_RECURSE

View File

@@ -8,8 +8,10 @@
/// @brief Macros used to convert NIL value
///
/// Is called both for special dictionary (unless #TYPVAL_ENCODE_ALLOW_SPECIALS
/// is false) and `v:null`. Accepts no arguments, but still must be
/// a function-like macros.
/// is false) and `v:null`.
///
/// @param tv Pointer to typval where value is stored. May not be NULL. May
/// point to special dictionary.
/// @def TYPVAL_ENCODE_CONV_BOOL
/// @brief Macros used to convert boolean value
@@ -17,12 +19,16 @@
/// Is called both for special dictionary (unless #TYPVAL_ENCODE_ALLOW_SPECIALS
/// is false) and `v:true`/`v:false`.
///
/// @param tv Pointer to typval where value is stored. May not be NULL. May
/// point to a special dictionary.
/// @param num Boolean value to convert. Value is an expression which
/// evaluates to some integer.
/// @def TYPVAL_ENCODE_CONV_NUMBER
/// @brief Macros used to convert integer
///
/// @param tv Pointer to typval where value is stored. May not be NULL. May
/// point to a special dictionary.
/// @param num Integer to convert, must accept both varnumber_T and int64_t.
/// @def TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
@@ -31,11 +37,15 @@
/// Not used if #TYPVAL_ENCODE_ALLOW_SPECIALS is false, but still must be
/// defined.
///
/// @param tv Pointer to typval where value is stored. May not be NULL. Points
/// to a special dictionary.
/// @param num Integer to convert, must accept uint64_t.
/// @def TYPVAL_ENCODE_CONV_FLOAT
/// @brief Macros used to convert floating-point number
///
/// @param tv Pointer to typval where value is stored. May not be NULL. May
/// point to a special dictionary.
/// @param flt Number to convert, must accept float_T.
/// @def TYPVAL_ENCODE_CONV_STRING
@@ -44,6 +54,8 @@
/// Is used to convert VAR_STRING objects as well as BIN strings represented as
/// special dictionary.
///
/// @param tv Pointer to typval where value is stored. May not be NULL. May
/// point to a special dictionary.
/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
/// @param len String length.
@@ -52,6 +64,11 @@
///
/// Is used to convert dictionary keys and STR strings represented as special
/// dictionaries.
///
/// @param tv Pointer to typval where value is stored. May be NULL. May
/// point to a special dictionary.
/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
/// @param len String length.
/// @def TYPVAL_ENCODE_CONV_EXT_STRING
/// @brief Macros used to convert EXT string
@@ -60,31 +77,29 @@
/// actually used if #TYPVAL_ENCODE_ALLOW_SPECIALS is false, but still must be
/// defined.
///
/// @param tv Pointer to typval where value is stored. May not be NULL. Points
/// to a special dictionary.
/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
/// @param len String length.
/// @param type EXT type.
/// @def TYPVAL_ENCODE_CONV_FUNC
/// @brief Macros used to convert a function reference
///
/// @param fun Function name.
/// @def TYPVAL_ENCODE_CONV_FUNC_START
/// @brief Macros used when starting to convert a funcref or a partial
///
/// @param tv Pointer to typval where value is stored. May not be NULL.
/// @param fun Function name.
/// @param is_partial True if converted function is a partial.
/// @param pt Pointer to partial or NULL.
/// @def TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
/// @brief Macros used before starting to convert partial arguments
///
/// @param tv Pointer to typval where value is stored. May not be NULL.
/// @param len Number of arguments. Zero for absent arguments or when
/// converting a funcref.
/// @def TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
/// @brief Macros used before starting to convert self dictionary
///
/// @param tv Pointer to typval where value is stored. May not be NULL.
/// @param len Number of arguments. May be zero for empty dictionary or -1 for
/// missing self dictionary, also when converting function
/// reference.
@@ -92,40 +107,47 @@
/// @def TYPVAL_ENCODE_CONV_FUNC_END
/// @brief Macros used after converting a funcref or a partial
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where value is stored. May not be NULL.
/// @def TYPVAL_ENCODE_CONV_EMPTY_LIST
/// @brief Macros used to convert an empty list
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where value is stored. May not be NULL.
/// @def TYPVAL_ENCODE_CONV_EMPTY_DICT
/// @brief Macros used to convert an empty dictionary
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where value is stored. May not be NULL. May
/// point to a special dictionary.
/// @def TYPVAL_ENCODE_CONV_LIST_START
/// @brief Macros used before starting to convert non-empty list
///
/// @param tv Pointer to typval where value is stored. May be NULL. May
/// point to a special dictionary.
/// @param len List length. Is an expression which evaluates to an integer.
/// @def TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
/// @brief Macros used after finishing converting non-last list item
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where list is stored. May be NULL.
/// @def TYPVAL_ENCODE_CONV_LIST_END
/// @brief Macros used after converting non-empty list
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where list is stored. May be NULL.
/// @def TYPVAL_ENCODE_CONV_DICT_START
/// @brief Macros used before starting to convert non-empty dictionary
///
/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
/// point to a special dictionary.
/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR
/// (for dictionaries represented as special lists).
/// @param len Dictionary length. Is an expression which evaluates to an
/// integer.
/// @def TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
/// @def TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
/// @brief Macros used to check special dictionary key
///
/// @param label Label for goto in case check was not successfull.
@@ -134,17 +156,26 @@
/// @def TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
/// @brief Macros used after finishing converting dictionary key
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
/// point to a special dictionary.
/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR
/// (for dictionaries represented as special lists).
/// @def TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
/// @brief Macros used after finishing converting non-last dictionary value
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
/// point to a special dictionary.
/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR
/// (for dictionaries represented as special lists).
/// @def TYPVAL_ENCODE_CONV_DICT_END
/// @brief Macros used after converting non-empty dictionary
///
/// Accepts no arguments, but still must be a function-like macros.
/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
/// point to a special dictionary.
/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR
/// (for dictionaries represented as special lists).
/// @def TYPVAL_ENCODE_CONV_RECURSE
/// @brief Macros used when self-containing container is detected
@@ -193,6 +224,8 @@
#include "nvim/func_attr.h"
#include "nvim/eval/typval_encode.h"
const dict_T *const TYPVAL_ENCODE_NODICT_VAR = NULL;
static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
void *const val, int *const val_copyID,
@@ -263,28 +296,28 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
{
switch (tv->v_type) {
case VAR_STRING: {
TYPVAL_ENCODE_CONV_STRING(tv->vval.v_string, tv_strlen(tv));
TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv));
break;
}
case VAR_NUMBER: {
TYPVAL_ENCODE_CONV_NUMBER(tv->vval.v_number);
TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number);
break;
}
case VAR_FLOAT: {
TYPVAL_ENCODE_CONV_FLOAT(tv->vval.v_float);
TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float);
break;
}
case VAR_FUNC: {
TYPVAL_ENCODE_CONV_FUNC_START(tv->vval.v_string, false, NULL);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(0);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(-1);
TYPVAL_ENCODE_CONV_FUNC_END();
TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
TYPVAL_ENCODE_CONV_FUNC_END(tv);
break;
}
case VAR_PARTIAL: {
partial_T *const pt = tv->vval.v_partial;
(void)pt;
TYPVAL_ENCODE_CONV_FUNC_START(pt->pt_name, true, pt);
TYPVAL_ENCODE_CONV_FUNC_START(tv, pt->pt_name);
_mp_push(*mpstack, ((MPConvStackVal) {
.type = kMPConvPartial,
.tv = tv,
@@ -299,12 +332,12 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
case VAR_LIST: {
if (tv->vval.v_list == NULL || tv->vval.v_list->lv_len == 0) {
TYPVAL_ENCODE_CONV_EMPTY_LIST();
TYPVAL_ENCODE_CONV_EMPTY_LIST(tv);
break;
}
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID,
kMPConvList);
TYPVAL_ENCODE_CONV_LIST_START(tv->vval.v_list->lv_len);
TYPVAL_ENCODE_CONV_LIST_START(tv, tv->vval.v_list->lv_len);
_mp_push(*mpstack, ((MPConvStackVal) {
.type = kMPConvList,
.tv = tv,
@@ -320,12 +353,12 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
case VAR_SPECIAL: {
switch (tv->vval.v_special) {
case kSpecialVarNull: {
TYPVAL_ENCODE_CONV_NIL();
TYPVAL_ENCODE_CONV_NIL(tv);
break;
}
case kSpecialVarTrue:
case kSpecialVarFalse: {
TYPVAL_ENCODE_CONV_BOOL(tv->vval.v_special == kSpecialVarTrue);
TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_special == kSpecialVarTrue);
break;
}
}
@@ -334,7 +367,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
case VAR_DICT: {
if (tv->vval.v_dict == NULL
|| tv->vval.v_dict->dv_hashtab.ht_used == 0) {
TYPVAL_ENCODE_CONV_EMPTY_DICT();
TYPVAL_ENCODE_CONV_EMPTY_DICT(tv);
break;
}
const dictitem_T *type_di;
@@ -357,14 +390,14 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
switch ((MessagePackType)i) {
case kMPNil: {
TYPVAL_ENCODE_CONV_NIL();
TYPVAL_ENCODE_CONV_NIL(tv);
break;
}
case kMPBoolean: {
if (val_di->di_tv.v_type != VAR_NUMBER) {
goto _convert_one_value_regular_dict;
}
TYPVAL_ENCODE_CONV_BOOL(val_di->di_tv.vval.v_number);
TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number);
break;
}
case kMPInteger: {
@@ -397,9 +430,9 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
| (uint64_t)(((uint64_t)high_bits) << 31)
| (uint64_t)low_bits);
if (sign > 0) {
TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(number);
TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number);
} else {
TYPVAL_ENCODE_CONV_NUMBER(-number);
TYPVAL_ENCODE_CONV_NUMBER(tv, -number);
}
break;
}
@@ -407,7 +440,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
if (val_di->di_tv.v_type != VAR_FLOAT) {
goto _convert_one_value_regular_dict;
}
TYPVAL_ENCODE_CONV_FLOAT(val_di->di_tv.vval.v_float);
TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float);
break;
}
case kMPString:
@@ -423,9 +456,9 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
goto _convert_one_value_regular_dict;
}
if (is_string) {
TYPVAL_ENCODE_CONV_STR_STRING(buf, len);
TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
} else {
TYPVAL_ENCODE_CONV_STRING(buf, len);
TYPVAL_ENCODE_CONV_STRING(tv, buf, len);
}
xfree(buf);
break;
@@ -437,7 +470,8 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list,
lv_copyID, copyID,
kMPConvList);
TYPVAL_ENCODE_CONV_LIST_START(val_di->di_tv.vval.v_list->lv_len);
TYPVAL_ENCODE_CONV_LIST_START(tv,
val_di->di_tv.vval.v_list->lv_len);
_mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvList,
@@ -456,7 +490,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
list_T *const val_list = val_di->di_tv.vval.v_list;
if (val_list == NULL || val_list->lv_len == 0) {
TYPVAL_ENCODE_CONV_EMPTY_DICT();
TYPVAL_ENCODE_CONV_EMPTY_DICT(tv);
break;
}
for (const listitem_T *li = val_list->lv_first; li != NULL;
@@ -468,7 +502,8 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID,
kMPConvPairs);
TYPVAL_ENCODE_CONV_DICT_START(val_list->lv_len);
TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR,
val_list->lv_len);
_mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvPairs,
@@ -499,7 +534,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
&len, &buf)) {
goto _convert_one_value_regular_dict;
}
TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type);
TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type);
xfree(buf);
break;
}
@@ -509,7 +544,8 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
_convert_one_value_regular_dict:
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID,
kMPConvDict);
TYPVAL_ENCODE_CONV_DICT_START(tv->vval.v_dict->dv_hashtab.ht_used);
TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict,
tv->vval.v_dict->dv_hashtab.ht_used);
_mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvDict,
@@ -566,11 +602,12 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
if (!cur_mpsv->data.d.todo) {
(void)_mp_pop(mpstack);
cur_mpsv->data.d.dict->dv_copyID = copyID - 1;
TYPVAL_ENCODE_CONV_DICT_END();
TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, cur_mpsv->tv->vval.v_dict);
continue;
} else if (cur_mpsv->data.d.todo
!= cur_mpsv->data.d.dict->dv_hashtab.ht_used) {
TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS();
TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv,
cur_mpsv->tv->vval.v_dict);
}
while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) {
cur_mpsv->data.d.hi++;
@@ -578,9 +615,10 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
dictitem_T *const di = HI2DI(cur_mpsv->data.d.hi);
cur_mpsv->data.d.todo--;
cur_mpsv->data.d.hi++;
TYPVAL_ENCODE_CONV_STR_STRING(&di->di_key[0],
TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0],
strlen((char *)&di->di_key[0]));
TYPVAL_ENCODE_CONV_DICT_AFTER_KEY();
TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
cur_mpsv->tv->vval.v_dict);
tv = &di->di_tv;
break;
}
@@ -588,10 +626,10 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
if (cur_mpsv->data.l.li == NULL) {
(void)_mp_pop(mpstack);
cur_mpsv->data.l.list->lv_copyID = copyID - 1;
TYPVAL_ENCODE_CONV_LIST_END();
TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv);
continue;
} else if (cur_mpsv->data.l.li != cur_mpsv->data.l.list->lv_first) {
TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS();
TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv);
}
tv = &cur_mpsv->data.l.li->li_tv;
cur_mpsv->data.l.li = cur_mpsv->data.l.li->li_next;
@@ -601,13 +639,14 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
if (cur_mpsv->data.l.li == NULL) {
(void)_mp_pop(mpstack);
cur_mpsv->data.l.list->lv_copyID = copyID - 1;
TYPVAL_ENCODE_CONV_DICT_END();
TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
continue;
} else if (cur_mpsv->data.l.li != cur_mpsv->data.l.list->lv_first) {
TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS();
TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(
cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
}
const list_T *const kv_pair = cur_mpsv->data.l.li->li_tv.vval.v_list;
TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(
TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(
encode_vim_to__error_ret, kv_pair->lv_first->li_tv);
if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME,
&mpstack, cur_mpsv,
@@ -616,19 +655,22 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
objname) == FAIL) {
goto encode_vim_to__error_ret;
}
TYPVAL_ENCODE_CONV_DICT_AFTER_KEY();
TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
TYPVAL_ENCODE_NODICT_VAR);
tv = &kv_pair->lv_last->li_tv;
cur_mpsv->data.l.li = cur_mpsv->data.l.li->li_next;
break;
}
case kMPConvPartial: {
partial_T *const pt = cur_mpsv->data.p.pt;
tv = cur_mpsv->tv;
switch (cur_mpsv->data.p.stage) {
case kMPConvPartialArgs: {
TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(pt == NULL ? 0 : pt->pt_argc);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv,
pt == NULL ? 0 : pt->pt_argc);
cur_mpsv->data.p.stage = kMPConvPartialSelf;
if (pt != NULL && pt->pt_argc > 0) {
TYPVAL_ENCODE_CONV_LIST_START(pt->pt_argc);
TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc);
_mp_push(mpstack, ((MPConvStackVal) {
.type = kMPConvPartialList,
.tv = NULL,
@@ -647,7 +689,7 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
cur_mpsv->data.p.stage = kMPConvPartialEnd;
dict_T *const dict = pt == NULL ? NULL : pt->pt_dict;
if (dict != NULL) {
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(dict->dv_hashtab.ht_used);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used);
const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
TYPVAL_ENCODE_FIRST_ARG_NAME,
dict, &dict->dv_copyID, &mpstack, copyID, kMPConvDict,
@@ -659,7 +701,8 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
continue;
}
}
TYPVAL_ENCODE_CONV_DICT_START(dict->dv_hashtab.ht_used);
TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict,
dict->dv_hashtab.ht_used);
_mp_push(mpstack, ((MPConvStackVal) {
.type = kMPConvDict,
.tv = NULL,
@@ -672,12 +715,12 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
},
}));
} else {
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(-1);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
}
break;
}
case kMPConvPartialEnd: {
TYPVAL_ENCODE_CONV_FUNC_END();
TYPVAL_ENCODE_CONV_FUNC_END(tv);
(void)_mp_pop(mpstack);
break;
}
@@ -687,10 +730,10 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
case kMPConvPartialList: {
if (!cur_mpsv->data.a.todo) {
(void)_mp_pop(mpstack);
TYPVAL_ENCODE_CONV_LIST_END();
TYPVAL_ENCODE_CONV_LIST_END(NULL);
continue;
} else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) {
TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS();
TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL);
}
tv = cur_mpsv->data.a.arg++;
cur_mpsv->data.a.todo--;

View File

@@ -284,4 +284,13 @@ static inline size_t tv_strlen(const typval_T *const tv)
#define _TYPVAL_ENCODE_CONVERT_ONE_VALUE \
_TYPVAL_ENCODE_CONVERT_ONE_VALUE_INNER(TYPVAL_ENCODE_NAME)
#define _TYPVAL_ENCODE_NODICT_VAR_INNER_2(name) \
_typval_encode_##name##_nodict_var
#define _TYPVAL_ENCODE_NODICT_VAR_INNER(name) \
_TYPVAL_ENCODE_NODICT_VAR_INNER_2(name)
/// Name of the dummy const dict_T *const variable
#define TYPVAL_ENCODE_NODICT_VAR \
_TYPVAL_ENCODE_NODICT_VAR_INNER(TYPVAL_ENCODE_NAME)
#endif // NVIM_EVAL_TYPVAL_ENCODE_H