mirror of
https://github.com/neovim/neovim.git
synced 2025-09-19 01:38:16 +00:00
*: Remove most calls to tv_list_item_alloc
Still left calls in eval/typval.c and test/unit/eval/helpers.lua. Latter is the only reason why function did not receive `static` modifier.
This commit is contained in:
@@ -787,16 +787,14 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < obj.data.array.size; i++) {
|
for (uint32_t i = 0; i < obj.data.array.size; i++) {
|
||||||
Object item = obj.data.array.items[i];
|
Object item = obj.data.array.items[i];
|
||||||
listitem_T *li = tv_list_item_alloc();
|
typval_T li_tv;
|
||||||
|
|
||||||
if (!object_to_vim(item, TV_LIST_ITEM_TV(li), err)) {
|
if (!object_to_vim(item, &li_tv, err)) {
|
||||||
// cleanup
|
|
||||||
tv_list_item_free(li);
|
|
||||||
tv_list_free(list);
|
tv_list_free(list);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tv_list_append(list, li);
|
tv_list_append_owned_tv(list, li_tv);
|
||||||
}
|
}
|
||||||
tv_list_ref(list);
|
tv_list_ref(list);
|
||||||
|
|
||||||
|
@@ -4874,8 +4874,6 @@ void partial_unref(partial_T *pt)
|
|||||||
static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
|
static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
|
||||||
{
|
{
|
||||||
list_T *l = NULL;
|
list_T *l = NULL;
|
||||||
typval_T tv;
|
|
||||||
listitem_T *item;
|
|
||||||
|
|
||||||
if (evaluate) {
|
if (evaluate) {
|
||||||
l = tv_list_alloc();
|
l = tv_list_alloc();
|
||||||
@@ -4883,13 +4881,13 @@ static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
|
|
||||||
*arg = skipwhite(*arg + 1);
|
*arg = skipwhite(*arg + 1);
|
||||||
while (**arg != ']' && **arg != NUL) {
|
while (**arg != ']' && **arg != NUL) {
|
||||||
if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */
|
typval_T tv;
|
||||||
|
if (eval1(arg, &tv, evaluate) == FAIL) { // Recursive!
|
||||||
goto failret;
|
goto failret;
|
||||||
|
}
|
||||||
if (evaluate) {
|
if (evaluate) {
|
||||||
item = tv_list_item_alloc();
|
tv.v_lock = VAR_UNLOCKED;
|
||||||
*TV_LIST_ITEM_TV(item) = tv;
|
tv_list_append_owned_tv(l, tv);
|
||||||
TV_LIST_ITEM_TV(item)->v_lock = VAR_UNLOCKED;
|
|
||||||
tv_list_append(l, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (**arg == ']') {
|
if (**arg == ']') {
|
||||||
@@ -11441,40 +11439,38 @@ static void dict_list(typval_T *const tv, typval_T *const rettv,
|
|||||||
tv_list_alloc_ret(rettv);
|
tv_list_alloc_ret(rettv);
|
||||||
|
|
||||||
TV_DICT_ITER(tv->vval.v_dict, di, {
|
TV_DICT_ITER(tv->vval.v_dict, di, {
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
typval_T tv = { .v_lock = VAR_UNLOCKED };
|
||||||
tv_list_append(rettv->vval.v_list, li);
|
|
||||||
|
|
||||||
switch (what) {
|
switch (what) {
|
||||||
case kDictListKeys: {
|
case kDictListKeys: {
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_STRING;
|
tv.v_type = VAR_STRING;
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
tv.vval.v_string = vim_strsave(di->di_key);
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_string = vim_strsave(di->di_key);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kDictListValues: {
|
case kDictListValues: {
|
||||||
tv_copy(&di->di_tv, TV_LIST_ITEM_TV(li));
|
tv_copy(&di->di_tv, &tv);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kDictListItems: {
|
case kDictListItems: {
|
||||||
// items()
|
// items()
|
||||||
list_T *const sub_l = tv_list_alloc();
|
list_T *const sub_l = tv_list_alloc();
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_LIST;
|
tv.v_type = VAR_LIST;
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
tv.vval.v_list = sub_l;
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_list = sub_l;
|
|
||||||
tv_list_ref(sub_l);
|
tv_list_ref(sub_l);
|
||||||
|
|
||||||
listitem_T *sub_li = tv_list_item_alloc();
|
tv_list_append_owned_tv(sub_l, (typval_T) {
|
||||||
tv_list_append(sub_l, sub_li);
|
.v_type = VAR_STRING,
|
||||||
TV_LIST_ITEM_TV(sub_li)->v_type = VAR_STRING;
|
.v_lock = VAR_UNLOCKED,
|
||||||
TV_LIST_ITEM_TV(sub_li)->v_lock = VAR_UNLOCKED;
|
.vval.v_string = (char_u *)xstrdup((const char *)di->di_key),
|
||||||
TV_LIST_ITEM_TV(sub_li)->vval.v_string = vim_strsave(di->di_key);
|
});
|
||||||
|
|
||||||
|
tv_list_append_tv(sub_l, &di->di_tv);
|
||||||
|
|
||||||
sub_li = tv_list_item_alloc();
|
|
||||||
tv_list_append(sub_l, sub_li);
|
|
||||||
tv_copy(&di->di_tv, TV_LIST_ITEM_TV(sub_li));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tv_list_append_owned_tv(rettv->vval.v_list, tv);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12762,13 +12758,12 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
goto f_msgpackparse_exit;
|
goto f_msgpackparse_exit;
|
||||||
}
|
}
|
||||||
if (result == MSGPACK_UNPACK_SUCCESS) {
|
if (result == MSGPACK_UNPACK_SUCCESS) {
|
||||||
listitem_T *li = tv_list_item_alloc();
|
typval_T tv = { .v_type = VAR_UNKNOWN };
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_UNKNOWN;
|
if (msgpack_to_vim(unpacked.data, &tv) == FAIL) {
|
||||||
tv_list_append(ret_list, li);
|
|
||||||
if (msgpack_to_vim(unpacked.data, TV_LIST_ITEM_TV(li)) == FAIL) {
|
|
||||||
EMSG2(_(e_invarg2), "Failed to convert msgpack string");
|
EMSG2(_(e_invarg2), "Failed to convert msgpack string");
|
||||||
goto f_msgpackparse_exit;
|
goto f_msgpackparse_exit;
|
||||||
}
|
}
|
||||||
|
tv_list_append_owned_tv(ret_list, tv);
|
||||||
}
|
}
|
||||||
if (result == MSGPACK_UNPACK_CONTINUE) {
|
if (result == MSGPACK_UNPACK_CONTINUE) {
|
||||||
if (rlret == OK) {
|
if (rlret == OK) {
|
||||||
@@ -13030,7 +13025,6 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
|
p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
|
||||||
++p) {
|
++p) {
|
||||||
if (*p == '\n' || readlen <= 0) {
|
if (*p == '\n' || readlen <= 0) {
|
||||||
listitem_T *li;
|
|
||||||
char_u *s = NULL;
|
char_u *s = NULL;
|
||||||
size_t len = p - start;
|
size_t len = p - start;
|
||||||
|
|
||||||
@@ -13057,11 +13051,11 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
prevlen = prevsize = 0;
|
prevlen = prevsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
li = tv_list_item_alloc();
|
tv_list_append_owned_tv(rettv->vval.v_list, (typval_T) {
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_STRING;
|
.v_type = VAR_STRING,
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
.v_lock = VAR_UNLOCKED,
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_string = s;
|
.vval.v_string = s,
|
||||||
tv_list_append(rettv->vval.v_list, li);
|
});
|
||||||
|
|
||||||
start = p + 1; /* step over newline */
|
start = p + 1; /* step over newline */
|
||||||
if ((++cnt >= maxline && maxline >= 0) || readlen <= 0)
|
if ((++cnt >= maxline && maxline >= 0) || readlen <= 0)
|
||||||
@@ -14310,11 +14304,7 @@ static void f_serverlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
// Copy addrs into a linked list.
|
// Copy addrs into a linked list.
|
||||||
list_T *l = tv_list_alloc_ret(rettv);
|
list_T *l = tv_list_alloc_ret(rettv);
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
listitem_T *li = tv_list_item_alloc();
|
tv_list_append_allocated_string(l, addrs[i]);
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_STRING;
|
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_string = (char_u *)addrs[i];
|
|
||||||
tv_list_append(l, li);
|
|
||||||
}
|
}
|
||||||
xfree(addrs);
|
xfree(addrs);
|
||||||
}
|
}
|
||||||
@@ -15619,12 +15609,7 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
for (int i = 0; i < ga.ga_len; i++) {
|
for (int i = 0; i < ga.ga_len; i++) {
|
||||||
char *p = ((char **)ga.ga_data)[i];
|
char *p = ((char **)ga.ga_data)[i];
|
||||||
|
tv_list_append_allocated_string(rettv->vval.v_list, p);
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_STRING;
|
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_LOCKED;
|
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_string = (char_u *)p;
|
|
||||||
tv_list_append(rettv->vval.v_list, li);
|
|
||||||
}
|
}
|
||||||
ga_clear(&ga);
|
ga_clear(&ga);
|
||||||
}
|
}
|
||||||
|
@@ -127,9 +127,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
assert(last_container.special_val == NULL);
|
assert(last_container.special_val == NULL);
|
||||||
listitem_T *obj_li = tv_list_item_alloc();
|
tv_list_append_owned_tv(last_container.container.vval.v_list, obj.val);
|
||||||
*TV_LIST_ITEM_TV(obj_li) = obj.val;
|
|
||||||
tv_list_append(last_container.container.vval.v_list, obj_li);
|
|
||||||
} else if (last_container.stack_index == kv_size(*stack) - 2) {
|
} else if (last_container.stack_index == kv_size(*stack) - 2) {
|
||||||
if (!obj.didcolon) {
|
if (!obj.didcolon) {
|
||||||
EMSG2(_("E474: Expected colon before dictionary value: %s"),
|
EMSG2(_("E474: Expected colon before dictionary value: %s"),
|
||||||
@@ -154,12 +152,8 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
|||||||
} else {
|
} else {
|
||||||
list_T *const kv_pair = tv_list_alloc();
|
list_T *const kv_pair = tv_list_alloc();
|
||||||
tv_list_append_list(last_container.special_val, kv_pair);
|
tv_list_append_list(last_container.special_val, kv_pair);
|
||||||
listitem_T *const key_li = tv_list_item_alloc();
|
tv_list_append_owned_tv(kv_pair, key.val);
|
||||||
*TV_LIST_ITEM_TV(key_li) = key.val;
|
tv_list_append_owned_tv(kv_pair, obj.val);
|
||||||
tv_list_append(kv_pair, key_li);
|
|
||||||
listitem_T *const val_li = tv_list_item_alloc();
|
|
||||||
*TV_LIST_ITEM_TV(val_li) = obj.val;
|
|
||||||
tv_list_append(kv_pair, val_li);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Object with key only
|
// Object with key only
|
||||||
@@ -1047,10 +1041,10 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
|||||||
.vval = { .v_list = list },
|
.vval = { .v_list = list },
|
||||||
};
|
};
|
||||||
for (size_t i = 0; i < mobj.via.array.size; i++) {
|
for (size_t i = 0; i < mobj.via.array.size; i++) {
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
// Not populated yet, need to create list item to push.
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_UNKNOWN;
|
tv_list_append_owned_tv(list, (typval_T) { .v_type = VAR_UNKNOWN });
|
||||||
tv_list_append(list, li);
|
if (msgpack_to_vim(mobj.via.array.ptr[i],
|
||||||
if (msgpack_to_vim(mobj.via.array.ptr[i], TV_LIST_ITEM_TV(li))
|
TV_LIST_ITEM_TV(tv_list_last(list)))
|
||||||
== FAIL) {
|
== FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -1095,20 +1089,20 @@ msgpack_to_vim_generic_map: {}
|
|||||||
for (size_t i = 0; i < mobj.via.map.size; i++) {
|
for (size_t i = 0; i < mobj.via.map.size; i++) {
|
||||||
list_T *const kv_pair = tv_list_alloc();
|
list_T *const kv_pair = tv_list_alloc();
|
||||||
tv_list_append_list(list, kv_pair);
|
tv_list_append_list(list, kv_pair);
|
||||||
listitem_T *const key_li = tv_list_item_alloc();
|
|
||||||
TV_LIST_ITEM_TV(key_li)->v_type = VAR_UNKNOWN;
|
typval_T key_tv = { .v_type = VAR_UNKNOWN };
|
||||||
tv_list_append(kv_pair, key_li);
|
if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_tv) == FAIL) {
|
||||||
listitem_T *const val_li = tv_list_item_alloc();
|
tv_clear(&key_tv);
|
||||||
TV_LIST_ITEM_TV(val_li)->v_type = VAR_UNKNOWN;
|
|
||||||
tv_list_append(kv_pair, val_li);
|
|
||||||
if (msgpack_to_vim(mobj.via.map.ptr[i].key, TV_LIST_ITEM_TV(key_li))
|
|
||||||
== FAIL) {
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (msgpack_to_vim(mobj.via.map.ptr[i].val, TV_LIST_ITEM_TV(val_li))
|
tv_list_append_owned_tv(kv_pair, key_tv);
|
||||||
== FAIL) {
|
|
||||||
|
typval_T val_tv = { .v_type = VAR_UNKNOWN };
|
||||||
|
if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_tv) == FAIL) {
|
||||||
|
tv_clear(&val_tv);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
tv_list_append_owned_tv(kv_pair, val_tv);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -393,19 +393,30 @@ void tv_list_append_tv(list_T *const l, typval_T *const tv)
|
|||||||
tv_list_append(l, li);
|
tv_list_append(l, li);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like tv_list_append_tv(), but tv is moved to a list
|
||||||
|
///
|
||||||
|
/// This means that it is no longer valid to use contents of the typval_T after
|
||||||
|
/// function exits.
|
||||||
|
void tv_list_append_owned_tv(list_T *const l, typval_T tv)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
listitem_T *const li = tv_list_item_alloc();
|
||||||
|
*TV_LIST_ITEM_TV(li) = tv;
|
||||||
|
tv_list_append(l, li);
|
||||||
|
}
|
||||||
|
|
||||||
/// Append a list to a list as one item
|
/// Append a list to a list as one item
|
||||||
///
|
///
|
||||||
/// @param[out] l List to append to.
|
/// @param[out] l List to append to.
|
||||||
/// @param[in,out] itemlist List to append. Reference count is increased.
|
/// @param[in,out] itemlist List to append. Reference count is increased.
|
||||||
void tv_list_append_list(list_T *const list, list_T *const itemlist)
|
void tv_list_append_list(list_T *const l, list_T *const itemlist)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
tv_list_append_owned_tv(l, (typval_T) {
|
||||||
|
.v_type = VAR_LIST,
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_LIST;
|
.v_lock = VAR_UNLOCKED,
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
.vval.v_list = itemlist,
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_list = itemlist;
|
});
|
||||||
tv_list_append(list, li);
|
|
||||||
tv_list_ref(itemlist);
|
tv_list_ref(itemlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,15 +424,14 @@ void tv_list_append_list(list_T *const list, list_T *const itemlist)
|
|||||||
///
|
///
|
||||||
/// @param[out] l List to append to.
|
/// @param[out] l List to append to.
|
||||||
/// @param[in,out] dict Dictionary to append. Reference count is increased.
|
/// @param[in,out] dict Dictionary to append. Reference count is increased.
|
||||||
void tv_list_append_dict(list_T *const list, dict_T *const dict)
|
void tv_list_append_dict(list_T *const l, dict_T *const dict)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
tv_list_append_owned_tv(l, (typval_T) {
|
||||||
|
.v_type = VAR_DICT,
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_DICT;
|
.v_lock = VAR_UNLOCKED,
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
.vval.v_dict = dict,
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_dict = dict;
|
});
|
||||||
tv_list_append(list, li);
|
|
||||||
if (dict != NULL) {
|
if (dict != NULL) {
|
||||||
dict->dv_refcount++;
|
dict->dv_refcount++;
|
||||||
}
|
}
|
||||||
@@ -438,14 +448,15 @@ void tv_list_append_string(list_T *const l, const char *const str,
|
|||||||
const ssize_t len)
|
const ssize_t len)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
if (str == NULL) {
|
tv_list_append_owned_tv(l, (typval_T) {
|
||||||
assert(len == 0 || len == -1);
|
.v_type = VAR_STRING,
|
||||||
tv_list_append_allocated_string(l, NULL);
|
.v_lock = VAR_UNLOCKED,
|
||||||
} else {
|
.vval.v_string = (str == NULL
|
||||||
tv_list_append_allocated_string(l, (len >= 0
|
? NULL
|
||||||
? xmemdupz(str, (size_t)len)
|
: (len >= 0
|
||||||
: xstrdup(str)));
|
? xmemdupz(str, (size_t)len)
|
||||||
}
|
: xstrdup(str))),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append given string to the list
|
/// Append given string to the list
|
||||||
@@ -457,12 +468,11 @@ void tv_list_append_string(list_T *const l, const char *const str,
|
|||||||
void tv_list_append_allocated_string(list_T *const l, char *const str)
|
void tv_list_append_allocated_string(list_T *const l, char *const str)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
tv_list_append_owned_tv(l, (typval_T) {
|
||||||
|
.v_type = VAR_STRING,
|
||||||
tv_list_append(l, li);
|
.v_lock = VAR_UNLOCKED,
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_STRING;
|
.vval.v_string = (char_u *)str,
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
});
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_string = (char_u *)str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append number to the list
|
/// Append number to the list
|
||||||
@@ -472,11 +482,11 @@ void tv_list_append_allocated_string(list_T *const l, char *const str)
|
|||||||
/// listitem_T.
|
/// listitem_T.
|
||||||
void tv_list_append_number(list_T *const l, const varnumber_T n)
|
void tv_list_append_number(list_T *const l, const varnumber_T n)
|
||||||
{
|
{
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
tv_list_append_owned_tv(l, (typval_T) {
|
||||||
TV_LIST_ITEM_TV(li)->v_type = VAR_NUMBER;
|
.v_type = VAR_NUMBER,
|
||||||
TV_LIST_ITEM_TV(li)->v_lock = VAR_UNLOCKED;
|
.v_lock = VAR_UNLOCKED,
|
||||||
TV_LIST_ITEM_TV(li)->vval.v_number = n;
|
.vval.v_number = n,
|
||||||
tv_list_append(l, li);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//{{{2 Operations on the whole list
|
//{{{2 Operations on the whole list
|
||||||
|
@@ -212,19 +212,27 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
const char *s = lua_tolstring(lstate, -2, &len);
|
const char *s = lua_tolstring(lstate, -2, &len);
|
||||||
if (cur.special) {
|
if (cur.special) {
|
||||||
list_T *const kv_pair = tv_list_alloc();
|
list_T *const kv_pair = tv_list_alloc();
|
||||||
|
|
||||||
tv_list_append_list(cur.tv->vval.v_list, kv_pair);
|
tv_list_append_list(cur.tv->vval.v_list, kv_pair);
|
||||||
listitem_T *const key = tv_list_item_alloc();
|
typval_T s_tv = decode_string(s, len, kTrue, false, false);
|
||||||
*TV_LIST_ITEM_TV(key) = decode_string(s, len, kTrue, false, false);
|
if (s_tv.v_type == VAR_UNKNOWN) {
|
||||||
tv_list_append(kv_pair, key);
|
|
||||||
if (TV_LIST_ITEM_TV(key)->v_type == VAR_UNKNOWN) {
|
|
||||||
ret = false;
|
ret = false;
|
||||||
tv_list_unref(kv_pair);
|
tv_list_unref(kv_pair);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
listitem_T *const val = tv_list_item_alloc();
|
tv_list_append_owned_tv(kv_pair, s_tv);
|
||||||
tv_list_append(kv_pair, val);
|
|
||||||
|
// Value: not populated yet, need to create list item to push.
|
||||||
|
tv_list_append_owned_tv(kv_pair, (typval_T) {
|
||||||
|
.v_type = VAR_UNKNOWN,
|
||||||
|
});
|
||||||
kv_push(stack, cur);
|
kv_push(stack, cur);
|
||||||
cur = (TVPopStackItem) { TV_LIST_ITEM_TV(val), false, false, 0 };
|
cur = (TVPopStackItem) {
|
||||||
|
.tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)),
|
||||||
|
.container = false,
|
||||||
|
.special = false,
|
||||||
|
.idx = 0,
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
dictitem_T *const di = tv_dict_item_alloc_len(s, len);
|
dictitem_T *const di = tv_dict_item_alloc_len(s, len);
|
||||||
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
|
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
|
||||||
@@ -244,10 +252,18 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
lua_pop(lstate, 2);
|
lua_pop(lstate, 2);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
listitem_T *const li = tv_list_item_alloc();
|
// Not populated yet, need to create list item to push.
|
||||||
tv_list_append(cur.tv->vval.v_list, li);
|
tv_list_append_owned_tv(cur.tv->vval.v_list, (typval_T) {
|
||||||
|
.v_type = VAR_UNKNOWN,
|
||||||
|
});
|
||||||
kv_push(stack, cur);
|
kv_push(stack, cur);
|
||||||
cur = (TVPopStackItem) { TV_LIST_ITEM_TV(li), false, false, 0 };
|
// TODO(ZyX-I): Use indexes, here list item *will* be reallocated.
|
||||||
|
cur = (TVPopStackItem) {
|
||||||
|
.tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)),
|
||||||
|
.container = false,
|
||||||
|
.special = false,
|
||||||
|
.idx = 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(!cur.container);
|
assert(!cur.container);
|
||||||
|
@@ -678,6 +678,66 @@ describe('typval.c', function()
|
|||||||
eq({int(-100500), int(100500)}, typvalt2lua(l_tv))
|
eq({int(-100500), int(100500)}, typvalt2lua(l_tv))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
describe('tv()', function()
|
||||||
|
itp('works', function()
|
||||||
|
local l_tv = lua2typvalt(empty_list)
|
||||||
|
local l = l_tv.vval.v_list
|
||||||
|
|
||||||
|
local l_l_tv = lua2typvalt(empty_list)
|
||||||
|
alloc_log:clear()
|
||||||
|
local l_l = l_l_tv.vval.v_list
|
||||||
|
eq(1, l_l.lv_refcount)
|
||||||
|
lib.tv_list_append_tv(l, l_l_tv)
|
||||||
|
eq(2, l_l.lv_refcount)
|
||||||
|
eq(l_l, l.lv_first.li_tv.vval.v_list)
|
||||||
|
alloc_log:check({
|
||||||
|
a.li(l.lv_first),
|
||||||
|
})
|
||||||
|
|
||||||
|
local l_s_tv = lua2typvalt('test')
|
||||||
|
alloc_log:check({
|
||||||
|
a.str(l_s_tv.vval.v_string, 'test'),
|
||||||
|
})
|
||||||
|
lib.tv_list_append_tv(l, l_s_tv)
|
||||||
|
alloc_log:check({
|
||||||
|
a.li(l.lv_last),
|
||||||
|
a.str(l.lv_last.li_tv.vval.v_string, 'test'),
|
||||||
|
})
|
||||||
|
|
||||||
|
eq({empty_list, 'test'}, typvalt2lua(l_tv))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
describe('owned tv()', function()
|
||||||
|
itp('works', function()
|
||||||
|
local l_tv = lua2typvalt(empty_list)
|
||||||
|
local l = l_tv.vval.v_list
|
||||||
|
|
||||||
|
local l_l_tv = lua2typvalt(empty_list)
|
||||||
|
alloc_log:clear()
|
||||||
|
local l_l = l_l_tv.vval.v_list
|
||||||
|
eq(1, l_l.lv_refcount)
|
||||||
|
lib.tv_list_append_owned_tv(l, l_l_tv)
|
||||||
|
eq(1, l_l.lv_refcount)
|
||||||
|
l_l.lv_refcount = l_l.lv_refcount + 1
|
||||||
|
eq(l_l, l.lv_first.li_tv.vval.v_list)
|
||||||
|
alloc_log:check({
|
||||||
|
a.li(l.lv_first),
|
||||||
|
})
|
||||||
|
|
||||||
|
local l_s_tv = ffi.gc(lua2typvalt('test'), nil)
|
||||||
|
alloc_log:check({
|
||||||
|
a.str(l_s_tv.vval.v_string, 'test'),
|
||||||
|
})
|
||||||
|
lib.tv_list_append_owned_tv(l, l_s_tv)
|
||||||
|
eq(l_s_tv.vval.v_string, l.lv_last.li_tv.vval.v_string)
|
||||||
|
l_s_tv.vval.v_string = nil
|
||||||
|
alloc_log:check({
|
||||||
|
a.li(l.lv_last),
|
||||||
|
})
|
||||||
|
|
||||||
|
eq({empty_list, 'test'}, typvalt2lua(l_tv))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
describe('copy()', function()
|
describe('copy()', function()
|
||||||
local function tv_list_copy(...)
|
local function tv_list_copy(...)
|
||||||
|
Reference in New Issue
Block a user