aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-01-03 06:35:32 +0300
committerZyX <kp-pav@yandex.ru>2017-01-03 06:39:23 +0300
commitff8944105d50f34ca114c4ebeaee6df8cb029dd5 (patch)
treeb120fba3bc62429f52d1ed22d615dd3c7023a012
parent5ba24318e2e16da57d2463df83ef0086446221c4 (diff)
downloadrneovim-ff8944105d50f34ca114c4ebeaee6df8cb029dd5.tar.gz
rneovim-ff8944105d50f34ca114c4ebeaee6df8cb029dd5.tar.bz2
rneovim-ff8944105d50f34ca114c4ebeaee6df8cb029dd5.zip
eval/typval_encode: Refactor arguments to argument macroses
Fixed local test failures somewhere in process.
-rw-r--r--src/nvim/api/private/helpers.c42
-rw-r--r--src/nvim/eval.c212
-rw-r--r--src/nvim/eval/encode.c116
-rw-r--r--src/nvim/eval/typval_encode.c.h165
-rw-r--r--src/nvim/eval/typval_encode.h9
5 files changed, 317 insertions, 227 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index a195b8c0a1..5bd76bc238 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -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
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 7b1365785f..79134d748a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -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_CONV_DICT_AFTER_KEY()
-
-#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS()
+#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_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)
+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(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
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 38f0863195..73133b7b29 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -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
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index 5c807bb169..8caffaf7f5 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -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--;
diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h
index 9208cdc752..5813059cda 100644
--- a/src/nvim/eval/typval_encode.h
+++ b/src/nvim/eval/typval_encode.h
@@ -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