mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
*: Hide list implementation in other files as well
This commit is contained in:
parent
5c1ddb5078
commit
ac4bbf55f6
@ -789,7 +789,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
|
||||
Object item = obj.data.array.items[i];
|
||||
listitem_T *li = tv_list_item_alloc();
|
||||
|
||||
if (!object_to_vim(item, &li->li_tv, err)) {
|
||||
if (!object_to_vim(item, TV_LIST_ITEM_TV(li), err)) {
|
||||
// cleanup
|
||||
tv_list_item_free(li);
|
||||
tv_list_free(list);
|
||||
|
@ -3536,19 +3536,19 @@ theend:
|
||||
/*
|
||||
* Add completions from a list.
|
||||
*/
|
||||
static void ins_compl_add_list(list_T *list)
|
||||
static void ins_compl_add_list(list_T *const list)
|
||||
{
|
||||
listitem_T *li;
|
||||
int dir = compl_direction;
|
||||
|
||||
/* Go through the List with matches and add each of them. */
|
||||
for (li = list->lv_first; li != NULL; li = li->li_next) {
|
||||
if (ins_compl_add_tv(&li->li_tv, dir) == OK)
|
||||
/* if dir was BACKWARD then honor it just once */
|
||||
// Go through the List with matches and add each of them.
|
||||
TV_LIST_ITER(list, li, {
|
||||
if (ins_compl_add_tv(TV_LIST_ITEM_TV(li), dir) == OK) {
|
||||
// If dir was BACKWARD then honor it just once.
|
||||
dir = FORWARD;
|
||||
else if (did_emsg)
|
||||
} else if (did_emsg) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -120,7 +120,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
||||
last_container = kv_last(*container_stack);
|
||||
}
|
||||
if (last_container.container.v_type == VAR_LIST) {
|
||||
if (last_container.container.vval.v_list->lv_len != 0
|
||||
if (tv_list_len(last_container.container.vval.v_list) != 0
|
||||
&& !obj.didcomma) {
|
||||
EMSG2(_("E474: Expected comma before list item: %s"), val_location);
|
||||
tv_clear(&obj.val);
|
||||
@ -128,7 +128,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
||||
}
|
||||
assert(last_container.special_val == NULL);
|
||||
listitem_T *obj_li = tv_list_item_alloc();
|
||||
obj_li->li_tv = 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) {
|
||||
if (!obj.didcolon) {
|
||||
@ -155,10 +155,10 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|
||||
list_T *const kv_pair = tv_list_alloc();
|
||||
tv_list_append_list(last_container.special_val, kv_pair);
|
||||
listitem_T *const key_li = tv_list_item_alloc();
|
||||
key_li->li_tv = key.val;
|
||||
*TV_LIST_ITEM_TV(key_li) = key.val;
|
||||
tv_list_append(kv_pair, key_li);
|
||||
listitem_T *const val_li = tv_list_item_alloc();
|
||||
val_li->li_tv = obj.val;
|
||||
*TV_LIST_ITEM_TV(val_li) = obj.val;
|
||||
tv_list_append(kv_pair, val_li);
|
||||
}
|
||||
} else {
|
||||
@ -738,8 +738,9 @@ json_decode_string_cycle_start:
|
||||
} else if (last_container.special_val == NULL
|
||||
? (last_container.container.v_type == VAR_DICT
|
||||
? (DICT_LEN(last_container.container.vval.v_dict) == 0)
|
||||
: (last_container.container.vval.v_list->lv_len == 0))
|
||||
: (last_container.special_val->lv_len == 0)) {
|
||||
: (tv_list_len(last_container.container.vval.v_list)
|
||||
== 0))
|
||||
: (tv_list_len(last_container.special_val) == 0)) {
|
||||
emsgf(_("E474: Leading comma: %.*s"), LENP(p, e));
|
||||
goto json_decode_string_fail;
|
||||
}
|
||||
@ -1047,9 +1048,10 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
||||
};
|
||||
for (size_t i = 0; i < mobj.via.array.size; i++) {
|
||||
listitem_T *const li = tv_list_item_alloc();
|
||||
li->li_tv.v_type = VAR_UNKNOWN;
|
||||
TV_LIST_ITEM_TV(li)->v_type = VAR_UNKNOWN;
|
||||
tv_list_append(list, li);
|
||||
if (msgpack_to_vim(mobj.via.array.ptr[i], &li->li_tv) == FAIL) {
|
||||
if (msgpack_to_vim(mobj.via.array.ptr[i], TV_LIST_ITEM_TV(li))
|
||||
== FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
@ -1094,15 +1096,17 @@ msgpack_to_vim_generic_map: {}
|
||||
list_T *const kv_pair = tv_list_alloc();
|
||||
tv_list_append_list(list, kv_pair);
|
||||
listitem_T *const key_li = tv_list_item_alloc();
|
||||
key_li->li_tv.v_type = VAR_UNKNOWN;
|
||||
TV_LIST_ITEM_TV(key_li)->v_type = VAR_UNKNOWN;
|
||||
tv_list_append(kv_pair, key_li);
|
||||
listitem_T *const val_li = tv_list_item_alloc();
|
||||
val_li->li_tv.v_type = VAR_UNKNOWN;
|
||||
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, &key_li->li_tv) == FAIL) {
|
||||
if (msgpack_to_vim(mobj.via.map.ptr[i].key, TV_LIST_ITEM_TV(key_li))
|
||||
== FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_li->li_tv) == FAIL) {
|
||||
if (msgpack_to_vim(mobj.via.map.ptr[i].val, TV_LIST_ITEM_TV(val_li))
|
||||
== FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
@ -53,17 +53,18 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
|
||||
list_T *const list = (list_T *) data;
|
||||
const char *const end = buf + len;
|
||||
const char *line_end = buf;
|
||||
listitem_T *li = list->lv_last;
|
||||
listitem_T *li = tv_list_last(list);
|
||||
|
||||
// Continue the last list element
|
||||
if (li != NULL) {
|
||||
line_end = xmemscan(buf, NL, len);
|
||||
if (line_end != buf) {
|
||||
const size_t line_length = (size_t)(line_end - buf);
|
||||
char *str = (char *)li->li_tv.vval.v_string;
|
||||
char *str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string;
|
||||
const size_t li_len = (str == NULL ? 0 : strlen(str));
|
||||
li->li_tv.vval.v_string = xrealloc(str, li_len + line_length + 1);
|
||||
str = (char *)li->li_tv.vval.v_string + li_len;
|
||||
TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(
|
||||
str, li_len + line_length + 1);
|
||||
str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
|
||||
memcpy(str, buf, line_length);
|
||||
str[line_length] = 0;
|
||||
memchrsub(str, NUL, NL, line_length);
|
||||
@ -135,21 +136,18 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
|
||||
}
|
||||
case kMPConvPairs:
|
||||
case kMPConvList: {
|
||||
int idx = 0;
|
||||
const listitem_T *li;
|
||||
for (li = v.data.l.list->lv_first;
|
||||
li != NULL && li->li_next != v.data.l.li;
|
||||
li = li->li_next) {
|
||||
idx++;
|
||||
}
|
||||
const listitem_T *const li = TV_LIST_ITEM_PREV(v.data.l.list,
|
||||
v.data.l.li);
|
||||
int idx = (int)tv_list_idx_of_item(v.data.l.list, li);
|
||||
if (v.type == kMPConvList
|
||||
|| li == NULL
|
||||
|| (li->li_tv.v_type != VAR_LIST
|
||||
&& li->li_tv.vval.v_list->lv_len <= 0)) {
|
||||
vim_snprintf((char *) IObuff, IOSIZE, idx_msg, idx);
|
||||
|| (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
|
||||
&& tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) <= 0)) {
|
||||
vim_snprintf((char *)IObuff, IOSIZE, idx_msg, idx);
|
||||
ga_concat(&msg_ga, IObuff);
|
||||
} else {
|
||||
typval_T key_tv = li->li_tv.vval.v_list->lv_first->li_tv;
|
||||
typval_T key_tv = *TV_LIST_ITEM_TV(
|
||||
tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list));
|
||||
char *const key = encode_tv2echo(&key_tv, NULL);
|
||||
vim_snprintf((char *) IObuff, IOSIZE, key_pair_msg, key, idx);
|
||||
xfree(key);
|
||||
@ -202,21 +200,17 @@ bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len,
|
||||
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
size_t len = 0;
|
||||
if (list != NULL) {
|
||||
for (const listitem_T *li = list->lv_first;
|
||||
li != NULL;
|
||||
li = li->li_next) {
|
||||
if (li->li_tv.v_type != VAR_STRING) {
|
||||
return false;
|
||||
}
|
||||
len++;
|
||||
if (li->li_tv.vval.v_string != 0) {
|
||||
len += STRLEN(li->li_tv.vval.v_string);
|
||||
}
|
||||
TV_LIST_ITER_CONST(list, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
|
||||
return false;
|
||||
}
|
||||
if (len) {
|
||||
len--;
|
||||
len++;
|
||||
if (TV_LIST_ITEM_TV(li)->vval.v_string != 0) {
|
||||
len += STRLEN(TV_LIST_ITEM_TV(li)->vval.v_string);
|
||||
}
|
||||
});
|
||||
if (len) {
|
||||
len--;
|
||||
}
|
||||
*ret_len = len;
|
||||
if (len == 0) {
|
||||
@ -253,31 +247,34 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
|
||||
char *const buf_end = buf + nbuf;
|
||||
char *p = buf;
|
||||
while (p < buf_end) {
|
||||
assert(state->li_length == 0 || state->li->li_tv.vval.v_string != NULL);
|
||||
assert(state->li_length == 0
|
||||
|| TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
|
||||
for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) {
|
||||
assert(state->li->li_tv.vval.v_string != NULL);
|
||||
const char ch = (char)state->li->li_tv.vval.v_string[state->offset++];
|
||||
assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
|
||||
const char ch = (char)(
|
||||
TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
|
||||
*p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch);
|
||||
}
|
||||
if (p < buf_end) {
|
||||
state->li = state->li->li_next;
|
||||
state->li = TV_LIST_ITEM_NEXT(state->list, state->li);
|
||||
if (state->li == NULL) {
|
||||
*read_bytes = (size_t) (p - buf);
|
||||
return OK;
|
||||
}
|
||||
*p++ = NL;
|
||||
if (state->li->li_tv.v_type != VAR_STRING) {
|
||||
if (TV_LIST_ITEM_TV(state->li)->v_type != VAR_STRING) {
|
||||
*read_bytes = (size_t) (p - buf);
|
||||
return FAIL;
|
||||
}
|
||||
state->offset = 0;
|
||||
state->li_length = (state->li->li_tv.vval.v_string == NULL
|
||||
state->li_length = (TV_LIST_ITEM_TV(state->li)->vval.v_string == NULL
|
||||
? 0
|
||||
: STRLEN(state->li->li_tv.vval.v_string));
|
||||
: STRLEN(TV_LIST_ITEM_TV(state->li)->vval.v_string));
|
||||
}
|
||||
}
|
||||
*read_bytes = nbuf;
|
||||
return (state->offset < state->li_length || state->li->li_next != NULL
|
||||
return ((state->offset < state->li_length
|
||||
|| TV_LIST_ITEM_NEXT(state->list, state->li) != NULL)
|
||||
? NOTDONE
|
||||
: OK);
|
||||
}
|
||||
@ -727,12 +724,11 @@ bool encode_check_json_key(const typval_T *const tv)
|
||||
if (val_di->di_tv.vval.v_list == NULL) {
|
||||
return true;
|
||||
}
|
||||
for (const listitem_T *li = val_di->di_tv.vval.v_list->lv_first;
|
||||
li != NULL; li = li->li_next) {
|
||||
if (li->li_tv.v_type != VAR_STRING) {
|
||||
TV_LIST_ITER_CONST(val_di->di_tv.vval.v_list, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,10 @@ int encode_vim_to_echo(garray_T *const packer,
|
||||
|
||||
/// Structure defining state for read_from_list()
|
||||
typedef struct {
|
||||
const list_T *const list; ///< List being currently read.
|
||||
const listitem_T *li; ///< Item currently read.
|
||||
size_t offset; ///< Byte offset inside the read item.
|
||||
size_t li_length; ///< Length of the string inside the read item.
|
||||
size_t offset; ///< Byte offset inside the read item.
|
||||
size_t li_length; ///< Length of the string inside the read item.
|
||||
} ListReaderState;
|
||||
|
||||
/// Initialize ListReaderState structure
|
||||
@ -43,11 +44,13 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
return (ListReaderState) {
|
||||
.li = list->lv_first,
|
||||
.list = list,
|
||||
.li = tv_list_first(list),
|
||||
.offset = 0,
|
||||
.li_length = (list->lv_first->li_tv.vval.v_string == NULL
|
||||
.li_length = (TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string == NULL
|
||||
? 0
|
||||
: STRLEN(list->lv_first->li_tv.vval.v_string)),
|
||||
: STRLEN(TV_LIST_ITEM_TV(
|
||||
tv_list_first(list))->vval.v_string)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -383,6 +383,22 @@ static inline listitem_T *tv_list_first(const list_T *const l)
|
||||
return l->lv_first;
|
||||
}
|
||||
|
||||
static inline listitem_T *tv_list_last(const list_T *const l)
|
||||
REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
/// Get last list item
|
||||
///
|
||||
/// @param[in] l List to get item from.
|
||||
///
|
||||
/// @return List item or NULL in case of an empty list.
|
||||
static inline listitem_T *tv_list_last(const list_T *const l)
|
||||
{
|
||||
if (l == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return l->lv_last;
|
||||
}
|
||||
|
||||
static inline long tv_dict_len(const dict_T *const d)
|
||||
REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
|
@ -355,14 +355,14 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
break;
|
||||
}
|
||||
case VAR_LIST: {
|
||||
if (tv->vval.v_list == NULL || tv->vval.v_list->lv_len == 0) {
|
||||
if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) {
|
||||
TYPVAL_ENCODE_CONV_EMPTY_LIST(tv);
|
||||
break;
|
||||
}
|
||||
const int saved_copyID = tv->vval.v_list->lv_copyID;
|
||||
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID,
|
||||
kMPConvList);
|
||||
TYPVAL_ENCODE_CONV_LIST_START(tv, tv->vval.v_list->lv_len);
|
||||
TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list));
|
||||
assert(saved_copyID != copyID && saved_copyID != copyID - 1);
|
||||
_mp_push(*mpstack, ((MPConvStackVal) {
|
||||
.type = kMPConvList,
|
||||
@ -371,7 +371,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
.data = {
|
||||
.l = {
|
||||
.list = tv->vval.v_list,
|
||||
.li = tv->vval.v_list->lv_first,
|
||||
.li = tv_list_first(tv->vval.v_list),
|
||||
},
|
||||
},
|
||||
}));
|
||||
@ -440,23 +440,43 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
// bits is not checked), other unsigned and have at most 31
|
||||
// non-zero bits (number of bits is not checked).
|
||||
if (val_di->di_tv.v_type != VAR_LIST
|
||||
|| (val_list = val_di->di_tv.vval.v_list) == NULL
|
||||
|| val_list->lv_len != 4
|
||||
|| val_list->lv_first->li_tv.v_type != VAR_NUMBER
|
||||
|| (sign = val_list->lv_first->li_tv.vval.v_number) == 0
|
||||
|| val_list->lv_first->li_next->li_tv.v_type != VAR_NUMBER
|
||||
|| (highest_bits =
|
||||
val_list->lv_first->li_next->li_tv.vval.v_number) < 0
|
||||
|| val_list->lv_last->li_prev->li_tv.v_type != VAR_NUMBER
|
||||
|| (high_bits =
|
||||
val_list->lv_last->li_prev->li_tv.vval.v_number) < 0
|
||||
|| val_list->lv_last->li_tv.v_type != VAR_NUMBER
|
||||
|| (low_bits = val_list->lv_last->li_tv.vval.v_number) < 0) {
|
||||
|| tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62)
|
||||
| (uint64_t)(((uint64_t)high_bits) << 31)
|
||||
| (uint64_t)low_bits);
|
||||
|
||||
const listitem_T *const sign_li = tv_list_first(val_list);
|
||||
if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER
|
||||
|| (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
|
||||
const listitem_T *const highest_bits_li = (
|
||||
TV_LIST_ITEM_NEXT(val_list, sign_li));
|
||||
if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER
|
||||
|| ((highest_bits
|
||||
= TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number)
|
||||
< 0)) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
|
||||
const listitem_T *const high_bits_li = (
|
||||
TV_LIST_ITEM_NEXT(val_list, highest_bits_li));
|
||||
if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER
|
||||
|| ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number)
|
||||
< 0)) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
|
||||
const listitem_T *const low_bits_li = tv_list_last(val_list);
|
||||
if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER
|
||||
|| ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number)
|
||||
< 0)) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
|
||||
const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62)
|
||||
| (uint64_t)(((uint64_t)high_bits) << 31)
|
||||
| (uint64_t)low_bits);
|
||||
if (sign > 0) {
|
||||
TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number);
|
||||
} else {
|
||||
@ -499,8 +519,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(tv,
|
||||
val_di->di_tv.vval.v_list->lv_len);
|
||||
TYPVAL_ENCODE_CONV_LIST_START(
|
||||
tv, tv_list_len(val_di->di_tv.vval.v_list));
|
||||
assert(saved_copyID != copyID && saved_copyID != copyID - 1);
|
||||
_mp_push(*mpstack, ((MPConvStackVal) {
|
||||
.tv = tv,
|
||||
@ -509,7 +529,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
.data = {
|
||||
.l = {
|
||||
.list = val_di->di_tv.vval.v_list,
|
||||
.li = val_di->di_tv.vval.v_list->lv_first,
|
||||
.li = tv_list_first(val_di->di_tv.vval.v_list),
|
||||
},
|
||||
},
|
||||
}));
|
||||
@ -520,22 +540,21 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
list_T *const val_list = val_di->di_tv.vval.v_list;
|
||||
if (val_list == NULL || val_list->lv_len == 0) {
|
||||
if (val_list == NULL || tv_list_len(val_list) == 0) {
|
||||
TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, TYPVAL_ENCODE_NODICT_VAR);
|
||||
break;
|
||||
}
|
||||
for (const listitem_T *li = val_list->lv_first; li != NULL;
|
||||
li = li->li_next) {
|
||||
if (li->li_tv.v_type != VAR_LIST
|
||||
|| li->li_tv.vval.v_list->lv_len != 2) {
|
||||
TV_LIST_ITER_CONST(val_list, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
|
||||
|| tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) != 2) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
}
|
||||
});
|
||||
const int saved_copyID = val_di->di_tv.vval.v_list->lv_copyID;
|
||||
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID,
|
||||
kMPConvPairs);
|
||||
TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR,
|
||||
val_list->lv_len);
|
||||
tv_list_len(val_list));
|
||||
assert(saved_copyID != copyID && saved_copyID != copyID - 1);
|
||||
_mp_push(*mpstack, ((MPConvStackVal) {
|
||||
.tv = tv,
|
||||
@ -544,7 +563,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
.data = {
|
||||
.l = {
|
||||
.list = val_list,
|
||||
.li = val_list->lv_first,
|
||||
.li = tv_list_first(val_list),
|
||||
},
|
||||
},
|
||||
}));
|
||||
@ -554,18 +573,22 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
const list_T *val_list;
|
||||
varnumber_T type;
|
||||
if (val_di->di_tv.v_type != VAR_LIST
|
||||
|| (val_list = val_di->di_tv.vval.v_list) == NULL
|
||||
|| val_list->lv_len != 2
|
||||
|| (val_list->lv_first->li_tv.v_type != VAR_NUMBER)
|
||||
|| (type = val_list->lv_first->li_tv.vval.v_number) > INT8_MAX
|
||||
|| tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2
|
||||
|| (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type
|
||||
!= VAR_NUMBER)
|
||||
|| ((type
|
||||
= TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number)
|
||||
> INT8_MAX)
|
||||
|| type < INT8_MIN
|
||||
|| (val_list->lv_last->li_tv.v_type != VAR_LIST)) {
|
||||
|| (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type
|
||||
!= VAR_LIST)) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
size_t len;
|
||||
char *buf;
|
||||
if (!encode_vim_list_to_buf(val_list->lv_last->li_tv.vval.v_list,
|
||||
&len, &buf)) {
|
||||
if (!encode_vim_list_to_buf(
|
||||
TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len,
|
||||
&buf)) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type);
|
||||
@ -674,11 +697,13 @@ typval_encode_stop_converting_one_item:
|
||||
cur_mpsv->data.l.list->lv_copyID = cur_mpsv->saved_copyID;
|
||||
TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv);
|
||||
continue;
|
||||
} else if (cur_mpsv->data.l.li != cur_mpsv->data.l.list->lv_first) {
|
||||
} else if (cur_mpsv->data.l.li
|
||||
!= tv_list_first(cur_mpsv->data.l.list)) {
|
||||
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;
|
||||
tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li);
|
||||
cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
|
||||
cur_mpsv->data.l.li);
|
||||
break;
|
||||
}
|
||||
case kMPConvPairs: {
|
||||
@ -687,24 +712,26 @@ typval_encode_stop_converting_one_item:
|
||||
cur_mpsv->data.l.list->lv_copyID = cur_mpsv->saved_copyID;
|
||||
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) {
|
||||
} else if (cur_mpsv->data.l.li
|
||||
!= tv_list_first(cur_mpsv->data.l.list)) {
|
||||
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;
|
||||
const list_T *const kv_pair = (
|
||||
TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list);
|
||||
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,
|
||||
&kv_pair->lv_first->li_tv,
|
||||
copyID,
|
||||
objname) == FAIL) {
|
||||
encode_vim_to__error_ret, *TV_LIST_ITEM_TV(tv_list_first(kv_pair)));
|
||||
if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv,
|
||||
TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname)
|
||||
== FAIL) {
|
||||
goto encode_vim_to__error_ret;
|
||||
}
|
||||
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;
|
||||
tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair));
|
||||
cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
|
||||
cur_mpsv->data.l.li);
|
||||
break;
|
||||
}
|
||||
case kMPConvPartial: {
|
||||
|
@ -6334,7 +6334,6 @@ char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
|
||||
void ex_oldfiles(exarg_T *eap)
|
||||
{
|
||||
list_T *l = get_vim_var_list(VV_OLDFILES);
|
||||
listitem_T *li;
|
||||
long nr = 0;
|
||||
|
||||
if (l == NULL) {
|
||||
@ -6342,19 +6341,22 @@ void ex_oldfiles(exarg_T *eap)
|
||||
} else {
|
||||
msg_start();
|
||||
msg_scroll = true;
|
||||
for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) {
|
||||
TV_LIST_ITER(l, li, {
|
||||
if (got_int) {
|
||||
break;
|
||||
}
|
||||
nr++;
|
||||
const char *fname = tv_get_string(&li->li_tv);
|
||||
const char *fname = tv_get_string(TV_LIST_ITEM_TV(li));
|
||||
if (!message_filtered((char_u *)fname)) {
|
||||
msg_outnum(nr);
|
||||
MSG_PUTS(": ");
|
||||
msg_outtrans((char_u *)tv_get_string(&li->li_tv));
|
||||
msg_outtrans((char_u *)tv_get_string(TV_LIST_ITEM_TV(li)));
|
||||
msg_clr_eos();
|
||||
msg_putchar('\n');
|
||||
ui_flush(); // output one line at a time
|
||||
os_breakcheck();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Assume "got_int" was set to truncate the listing.
|
||||
got_int = false;
|
||||
@ -6364,7 +6366,7 @@ void ex_oldfiles(exarg_T *eap)
|
||||
quit_more = false;
|
||||
nr = prompt_for_number(false);
|
||||
msg_starthere();
|
||||
if (nr > 0 && nr <= l->lv_len) {
|
||||
if (nr > 0 && nr <= tv_list_len(l)) {
|
||||
const char *const p = tv_list_find_str(l, nr - 1);
|
||||
if (p == NULL) {
|
||||
return;
|
||||
|
@ -2618,20 +2618,20 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
||||
}
|
||||
varnumber_T prev_end = 0;
|
||||
int i = 0;
|
||||
for (const listitem_T *li = tv.vval.v_list->lv_first;
|
||||
li != NULL; li = li->li_next, i++) {
|
||||
if (li->li_tv.v_type != VAR_LIST) {
|
||||
TV_LIST_ITER_CONST(tv.vval.v_list, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST) {
|
||||
PRINT_ERRMSG(_("E5401: List item %i is not a List"), i);
|
||||
goto color_cmdline_error;
|
||||
}
|
||||
const list_T *const l = li->li_tv.vval.v_list;
|
||||
const list_T *const l = TV_LIST_ITEM_TV(li)->vval.v_list;
|
||||
if (tv_list_len(l) != 3) {
|
||||
PRINT_ERRMSG(_("E5402: List item %i has incorrect length: %li /= 3"),
|
||||
i, tv_list_len(l));
|
||||
goto color_cmdline_error;
|
||||
}
|
||||
bool error = false;
|
||||
const varnumber_T start = tv_get_number_chk(&l->lv_first->li_tv, &error);
|
||||
const varnumber_T start = (
|
||||
tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error));
|
||||
if (error) {
|
||||
goto color_cmdline_error;
|
||||
} else if (!(prev_end <= start && start < colored_ccline->cmdlen)) {
|
||||
@ -2651,8 +2651,8 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
||||
.attr = 0,
|
||||
}));
|
||||
}
|
||||
const varnumber_T end = tv_get_number_chk(&l->lv_first->li_next->li_tv,
|
||||
&error);
|
||||
const varnumber_T end = tv_get_number_chk(
|
||||
TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error);
|
||||
if (error) {
|
||||
goto color_cmdline_error;
|
||||
} else if (!(start < end && end <= colored_ccline->cmdlen)) {
|
||||
@ -2668,7 +2668,8 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
||||
goto color_cmdline_error;
|
||||
}
|
||||
prev_end = end;
|
||||
const char *const group = tv_get_string_chk(&l->lv_last->li_tv);
|
||||
const char *const group = tv_get_string_chk(
|
||||
TV_LIST_ITEM_TV(tv_list_last(l)));
|
||||
if (group == NULL) {
|
||||
goto color_cmdline_error;
|
||||
}
|
||||
@ -2679,7 +2680,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
|
||||
.end = end,
|
||||
.attr = attr,
|
||||
}));
|
||||
}
|
||||
});
|
||||
if (prev_end < colored_ccline->cmdlen) {
|
||||
kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
|
||||
.start = prev_end,
|
||||
@ -5021,24 +5022,24 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
|
||||
*/
|
||||
static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
|
||||
{
|
||||
list_T *retlist;
|
||||
listitem_T *li;
|
||||
garray_T ga;
|
||||
|
||||
retlist = call_user_expand_func((user_expand_func_T)call_func_retlist, xp,
|
||||
num_file, file);
|
||||
list_T *const retlist = call_user_expand_func(
|
||||
(user_expand_func_T)call_func_retlist, xp, num_file, file);
|
||||
if (retlist == NULL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
garray_T ga;
|
||||
ga_init(&ga, (int)sizeof(char *), 3);
|
||||
/* Loop over the items in the list. */
|
||||
for (li = retlist->lv_first; li != NULL; li = li->li_next) {
|
||||
if (li->li_tv.v_type != VAR_STRING || li->li_tv.vval.v_string == NULL)
|
||||
continue; /* Skip non-string items and empty strings */
|
||||
// Loop over the items in the list.
|
||||
TV_LIST_ITER_CONST(retlist, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING
|
||||
|| TV_LIST_ITEM_TV(li)->vval.v_string == NULL) {
|
||||
continue; // Skip non-string items and empty strings.
|
||||
}
|
||||
|
||||
GA_APPEND(char_u *, &ga, vim_strsave(li->li_tv.vval.v_string));
|
||||
}
|
||||
GA_APPEND(char *, &ga, xstrdup(
|
||||
(const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
|
||||
});
|
||||
tv_list_unref(retlist);
|
||||
|
||||
*file = ga.ga_data;
|
||||
|
@ -214,9 +214,9 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
||||
list_T *const kv_pair = tv_list_alloc();
|
||||
tv_list_append_list(cur.tv->vval.v_list, kv_pair);
|
||||
listitem_T *const key = tv_list_item_alloc();
|
||||
key->li_tv = decode_string(s, len, kTrue, false, false);
|
||||
*TV_LIST_ITEM_TV(key) = decode_string(s, len, kTrue, false, false);
|
||||
tv_list_append(kv_pair, key);
|
||||
if (key->li_tv.v_type == VAR_UNKNOWN) {
|
||||
if (TV_LIST_ITEM_TV(key)->v_type == VAR_UNKNOWN) {
|
||||
ret = false;
|
||||
tv_list_unref(kv_pair);
|
||||
continue;
|
||||
@ -224,7 +224,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
||||
listitem_T *const val = tv_list_item_alloc();
|
||||
tv_list_append(kv_pair, val);
|
||||
kv_push(stack, cur);
|
||||
cur = (TVPopStackItem) { &val->li_tv, false, false, 0 };
|
||||
cur = (TVPopStackItem) { TV_LIST_ITEM_TV(val), false, false, 0 };
|
||||
} else {
|
||||
dictitem_T *const di = tv_dict_item_alloc_len(s, len);
|
||||
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
|
||||
@ -239,7 +239,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
||||
}
|
||||
} else {
|
||||
assert(cur.tv->v_type == VAR_LIST);
|
||||
lua_rawgeti(lstate, -1, cur.tv->vval.v_list->lv_len + 1);
|
||||
lua_rawgeti(lstate, -1, tv_list_len(cur.tv->vval.v_list) + 1);
|
||||
if (lua_isnil(lstate, -1)) {
|
||||
lua_pop(lstate, 2);
|
||||
continue;
|
||||
@ -247,7 +247,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
||||
listitem_T *const li = tv_list_item_alloc();
|
||||
tv_list_append(cur.tv->vval.v_list, li);
|
||||
kv_push(stack, cur);
|
||||
cur = (TVPopStackItem) { &li->li_tv, false, false, 0 };
|
||||
cur = (TVPopStackItem) { TV_LIST_ITEM_TV(li), false, false, 0 };
|
||||
}
|
||||
}
|
||||
assert(!cur.container);
|
||||
|
@ -4854,9 +4854,8 @@ static void *get_reg_wrap_one_line(char_u *s, int flags)
|
||||
if (!(flags & kGRegList)) {
|
||||
return s;
|
||||
}
|
||||
list_T *list = tv_list_alloc();
|
||||
tv_list_append_string(list, NULL, 0);
|
||||
list->lv_first->li_tv.vval.v_string = s;
|
||||
list_T *const list = tv_list_alloc();
|
||||
tv_list_append_allocated_string(list, (char *)s);
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -5610,12 +5609,13 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
|
||||
|
||||
list_T *res = result.vval.v_list;
|
||||
list_T *lines = NULL;
|
||||
if (res->lv_len == 2 && res->lv_first->li_tv.v_type == VAR_LIST) {
|
||||
lines = res->lv_first->li_tv.vval.v_list;
|
||||
if (res->lv_last->li_tv.v_type != VAR_STRING) {
|
||||
if (tv_list_len(res) == 2
|
||||
&& TV_LIST_ITEM_TV(tv_list_first(res))->v_type == VAR_LIST) {
|
||||
lines = TV_LIST_ITEM_TV(tv_list_first(res))->vval.v_list;
|
||||
if (TV_LIST_ITEM_TV(tv_list_last(res))->v_type != VAR_STRING) {
|
||||
goto err;
|
||||
}
|
||||
char_u *regtype = res->lv_last->li_tv.vval.v_string;
|
||||
char_u *regtype = TV_LIST_ITEM_TV(tv_list_last(res))->vval.v_string;
|
||||
if (regtype == NULL || strlen((char*)regtype) > 1) {
|
||||
goto err;
|
||||
}
|
||||
@ -5641,20 +5641,21 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
|
||||
reg->y_type = kMTUnknown;
|
||||
}
|
||||
|
||||
reg->y_array = xcalloc((size_t)lines->lv_len, sizeof(uint8_t *));
|
||||
reg->y_size = (size_t)lines->lv_len;
|
||||
reg->y_array = xcalloc((size_t)tv_list_len(lines), sizeof(char_u *));
|
||||
reg->y_size = (size_t)tv_list_len(lines);
|
||||
reg->additional_data = NULL;
|
||||
reg->timestamp = 0;
|
||||
// Timestamp is not saved for clipboard registers because clipboard registers
|
||||
// are not saved in the ShaDa file.
|
||||
|
||||
int i = 0;
|
||||
for (listitem_T *li = lines->lv_first; li != NULL; li = li->li_next) {
|
||||
if (li->li_tv.v_type != VAR_STRING) {
|
||||
TV_LIST_ITER_CONST(lines, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
|
||||
goto err;
|
||||
}
|
||||
reg->y_array[i++] = (char_u *)xstrdupnul((char *)li->li_tv.vval.v_string);
|
||||
}
|
||||
reg->y_array[i++] = (char_u *)xstrdupnul(
|
||||
(const char *)TV_LIST_ITEM_TV(li)->vval.v_string);
|
||||
});
|
||||
|
||||
if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) {
|
||||
// a known-to-be charwise yank might have a final linebreak
|
||||
|
@ -156,6 +156,7 @@ typedef struct {
|
||||
FILE *fd;
|
||||
typval_T *tv;
|
||||
char_u *p_str;
|
||||
list_T *p_list;
|
||||
listitem_T *p_li;
|
||||
buf_T *buf;
|
||||
linenr_T buflnum;
|
||||
@ -516,17 +517,17 @@ static int qf_get_next_list_line(qfstate_T *state)
|
||||
|
||||
// Get the next line from the supplied list
|
||||
while (p_li != NULL
|
||||
&& (p_li->li_tv.v_type != VAR_STRING
|
||||
|| p_li->li_tv.vval.v_string == NULL)) {
|
||||
p_li = p_li->li_next; // Skip non-string items
|
||||
&& (TV_LIST_ITEM_TV(p_li)->v_type != VAR_STRING
|
||||
|| TV_LIST_ITEM_TV(p_li)->vval.v_string == NULL)) {
|
||||
p_li = TV_LIST_ITEM_NEXT(state->p_list, p_li); // Skip non-string items.
|
||||
}
|
||||
|
||||
if (p_li == NULL) { // End of the list
|
||||
if (p_li == NULL) { // End of the list.
|
||||
state->p_li = NULL;
|
||||
return QF_END_OF_INPUT;
|
||||
}
|
||||
|
||||
len = STRLEN(p_li->li_tv.vval.v_string);
|
||||
len = STRLEN(TV_LIST_ITEM_TV(p_li)->vval.v_string);
|
||||
if (len > IOSIZE - 2) {
|
||||
state->linebuf = qf_grow_linebuf(state, len);
|
||||
} else {
|
||||
@ -534,9 +535,10 @@ static int qf_get_next_list_line(qfstate_T *state)
|
||||
state->linelen = len;
|
||||
}
|
||||
|
||||
STRLCPY(state->linebuf, p_li->li_tv.vval.v_string, state->linelen + 1);
|
||||
STRLCPY(state->linebuf, TV_LIST_ITEM_TV(p_li)->vval.v_string,
|
||||
state->linelen + 1);
|
||||
|
||||
state->p_li = p_li->li_next; // next item
|
||||
state->p_li = TV_LIST_ITEM_NEXT(state->p_list, p_li);
|
||||
return QF_OK;
|
||||
}
|
||||
|
||||
@ -983,7 +985,7 @@ qf_init_ext(
|
||||
)
|
||||
{
|
||||
qfstate_T state = { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
|
||||
NULL, 0, 0 };
|
||||
NULL, NULL, 0, 0 };
|
||||
qffields_T fields = { NULL, NULL, 0, 0L, 0, false, NULL, 0, 0, 0 };
|
||||
qfline_T *old_last = NULL;
|
||||
bool adding = false;
|
||||
@ -1064,7 +1066,8 @@ qf_init_ext(
|
||||
if (tv->v_type == VAR_STRING) {
|
||||
state.p_str = tv->vval.v_string;
|
||||
} else if (tv->v_type == VAR_LIST) {
|
||||
state.p_li = tv->vval.v_list->lv_first;
|
||||
state.p_list = tv->vval.v_list;
|
||||
state.p_li = tv_list_first(tv->vval.v_list);
|
||||
}
|
||||
state.tv = tv;
|
||||
}
|
||||
@ -4100,7 +4103,6 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
static int qf_add_entries(qf_info_T *qi, list_T *list, char_u *title,
|
||||
int action)
|
||||
{
|
||||
listitem_T *li;
|
||||
dict_T *d;
|
||||
qfline_T *old_last = NULL;
|
||||
int retval = OK;
|
||||
@ -4117,13 +4119,15 @@ static int qf_add_entries(qf_info_T *qi, list_T *list, char_u *title,
|
||||
qf_store_title(qi, title);
|
||||
}
|
||||
|
||||
for (li = list->lv_first; li != NULL; li = li->li_next) {
|
||||
if (li->li_tv.v_type != VAR_DICT)
|
||||
continue; /* Skip non-dict items */
|
||||
TV_LIST_ITER_CONST(list, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT) {
|
||||
continue; // Skip non-dict items.
|
||||
}
|
||||
|
||||
d = li->li_tv.vval.v_dict;
|
||||
if (d == NULL)
|
||||
d = TV_LIST_ITEM_TV(li)->vval.v_dict;
|
||||
if (d == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char *const filename = tv_dict_get_string(d, "filename", true);
|
||||
int bufnum = (int)tv_dict_get_number(d, "bufnr");
|
||||
@ -4175,7 +4179,7 @@ static int qf_add_entries(qf_info_T *qi, list_T *list, char_u *title,
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (qi->qf_lists[qi->qf_curlist].qf_index == 0) {
|
||||
// no valid entry
|
||||
|
@ -6477,10 +6477,6 @@ static regsubmatch_T rsm; // can only be used when can_f_submatch is true
|
||||
/// vim_regsub_both().
|
||||
static int fill_submatch_list(int argc, typval_T *argv, int argcount)
|
||||
{
|
||||
listitem_T *li;
|
||||
int i;
|
||||
char_u *s;
|
||||
|
||||
if (argcount == 0) {
|
||||
// called function doesn't take an argument
|
||||
return 0;
|
||||
@ -6490,28 +6486,26 @@ static int fill_submatch_list(int argc, typval_T *argv, int argcount)
|
||||
init_static_list((staticList10_T *)(argv->vval.v_list));
|
||||
|
||||
// There are always 10 list items in staticList10_T.
|
||||
li = argv->vval.v_list->lv_first;
|
||||
for (i = 0; i < 10; i++) {
|
||||
s = rsm.sm_match->startp[i];
|
||||
listitem_T *li = tv_list_first(argv->vval.v_list);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
char_u *s = rsm.sm_match->startp[i];
|
||||
if (s == NULL || rsm.sm_match->endp[i] == NULL) {
|
||||
s = NULL;
|
||||
} else {
|
||||
s = vim_strnsave(s, (int)(rsm.sm_match->endp[i] - s));
|
||||
}
|
||||
li->li_tv.v_type = VAR_STRING;
|
||||
li->li_tv.vval.v_string = s;
|
||||
li = li->li_next;
|
||||
TV_LIST_ITEM_TV(li)->v_type = VAR_STRING;
|
||||
TV_LIST_ITEM_TV(li)->vval.v_string = s;
|
||||
li = TV_LIST_ITEM_NEXT(argv->vval.v_list, li);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void clear_submatch_list(staticList10_T *sl)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
xfree(sl->sl_items[i].li_tv.vval.v_string);
|
||||
}
|
||||
TV_LIST_ITER(&sl->sl_list, li, {
|
||||
xfree(TV_LIST_ITEM_TV(li)->vval.v_string);
|
||||
});
|
||||
}
|
||||
|
||||
/// vim_regsub() - perform substitutions after a vim_regexec() or
|
||||
@ -6651,6 +6645,7 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
|
||||
rettv.vval.v_string = NULL;
|
||||
argv[0].v_type = VAR_LIST;
|
||||
argv[0].vval.v_list = &matchList.sl_list;
|
||||
// FIXME: Abstract away
|
||||
matchList.sl_list.lv_len = 0;
|
||||
if (expr->v_type == VAR_FUNC) {
|
||||
s = expr->vval.v_string;
|
||||
|
@ -1180,8 +1180,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
|
||||
list_T *oldfiles_list = get_vim_var_list(VV_OLDFILES);
|
||||
const bool force = flags & kShaDaForceit;
|
||||
const bool get_old_files = (flags & (kShaDaGetOldfiles | kShaDaForceit)
|
||||
&& (force || oldfiles_list == NULL
|
||||
|| oldfiles_list->lv_len == 0));
|
||||
&& (force || tv_list_len(oldfiles_list) == 0));
|
||||
const bool want_marks = flags & kShaDaWantMarks;
|
||||
const unsigned srni_flags = (unsigned) (
|
||||
(flags & kShaDaWantInfo
|
||||
@ -1599,13 +1598,13 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
|
||||
#define DUMP_ADDITIONAL_ELEMENTS(src, what) \
|
||||
do { \
|
||||
if ((src) != NULL) { \
|
||||
for (listitem_T *li = (src)->lv_first; li != NULL; li = li->li_next) { \
|
||||
if (encode_vim_to_msgpack(spacker, &li->li_tv, \
|
||||
TV_LIST_ITER((src), li, { \
|
||||
if (encode_vim_to_msgpack(spacker, TV_LIST_ITEM_TV(li), \
|
||||
_("additional elements of ShaDa " what)) \
|
||||
== FAIL) { \
|
||||
goto shada_pack_entry_error; \
|
||||
} \
|
||||
} \
|
||||
}); \
|
||||
} \
|
||||
} while (0)
|
||||
#define DUMP_ADDITIONAL_DATA(src, what) \
|
||||
@ -1648,9 +1647,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
|
||||
const bool is_hist_search =
|
||||
entry.data.history_item.histtype == HIST_SEARCH;
|
||||
const size_t arr_size = 2 + (size_t) is_hist_search + (size_t) (
|
||||
entry.data.history_item.additional_elements == NULL
|
||||
? 0
|
||||
: entry.data.history_item.additional_elements->lv_len);
|
||||
tv_list_len(entry.data.history_item.additional_elements));
|
||||
msgpack_pack_array(spacker, arr_size);
|
||||
msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
|
||||
PACK_BIN(cstr_as_string(entry.data.history_item.string));
|
||||
@ -1663,9 +1660,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
|
||||
}
|
||||
case kSDItemVariable: {
|
||||
const size_t arr_size = 2 + (size_t) (
|
||||
entry.data.global_var.additional_elements == NULL
|
||||
? 0
|
||||
: entry.data.global_var.additional_elements->lv_len);
|
||||
tv_list_len(entry.data.global_var.additional_elements));
|
||||
msgpack_pack_array(spacker, arr_size);
|
||||
const String varname = cstr_as_string(entry.data.global_var.name);
|
||||
PACK_BIN(varname);
|
||||
@ -1685,9 +1680,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
|
||||
}
|
||||
case kSDItemSubString: {
|
||||
const size_t arr_size = 1 + (size_t) (
|
||||
entry.data.sub_string.additional_elements == NULL
|
||||
? 0
|
||||
: entry.data.sub_string.additional_elements->lv_len);
|
||||
tv_list_len(entry.data.sub_string.additional_elements));
|
||||
msgpack_pack_array(spacker, arr_size);
|
||||
PACK_BIN(cstr_as_string(entry.data.sub_string.sub));
|
||||
DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements,
|
||||
|
@ -3213,26 +3213,25 @@ spell_find_suggest (
|
||||
// Find suggestions by evaluating expression "expr".
|
||||
static void spell_suggest_expr(suginfo_T *su, char_u *expr)
|
||||
{
|
||||
list_T *list;
|
||||
listitem_T *li;
|
||||
int score;
|
||||
const char *p;
|
||||
|
||||
// The work is split up in a few parts to avoid having to export
|
||||
// suginfo_T.
|
||||
// First evaluate the expression and get the resulting list.
|
||||
list = eval_spell_expr(su->su_badword, expr);
|
||||
list_T *const list = eval_spell_expr(su->su_badword, expr);
|
||||
if (list != NULL) {
|
||||
// Loop over the items in the list.
|
||||
for (li = list->lv_first; li != NULL; li = li->li_next)
|
||||
if (li->li_tv.v_type == VAR_LIST) {
|
||||
TV_LIST_ITER(list, li, {
|
||||
if (TV_LIST_ITEM_TV(li)->v_type == VAR_LIST) {
|
||||
// Get the word and the score from the items.
|
||||
score = get_spellword(li->li_tv.vval.v_list, &p);
|
||||
score = get_spellword(TV_LIST_ITEM_TV(li)->vval.v_list, &p);
|
||||
if (score >= 0 && score <= su->su_maxscore) {
|
||||
add_suggestion(su, &su->su_ga, (const char_u *)p, su->su_badlen,
|
||||
score, 0, true, su->su_sallang, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
tv_list_unref(list);
|
||||
}
|
||||
|
||||
|
@ -5579,30 +5579,26 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
|
||||
// Set up position matches
|
||||
if (pos_list != NULL)
|
||||
{
|
||||
linenr_T toplnum = 0;
|
||||
linenr_T botlnum = 0;
|
||||
listitem_T *li;
|
||||
int i;
|
||||
linenr_T toplnum = 0;
|
||||
linenr_T botlnum = 0;
|
||||
|
||||
for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
|
||||
i++, li = li->li_next) {
|
||||
linenr_T lnum = 0;
|
||||
colnr_T col = 0;
|
||||
int len = 1;
|
||||
list_T *subl;
|
||||
listitem_T *subli;
|
||||
int i = 0;
|
||||
TV_LIST_ITER(pos_list, li, {
|
||||
linenr_T lnum = 0;
|
||||
colnr_T col = 0;
|
||||
int len = 1;
|
||||
bool error = false;
|
||||
|
||||
if (li->li_tv.v_type == VAR_LIST) {
|
||||
subl = li->li_tv.vval.v_list;
|
||||
if (TV_LIST_ITEM_TV(li)->v_type == VAR_LIST) {
|
||||
const list_T *const subl = TV_LIST_ITEM_TV(li)->vval.v_list;
|
||||
if (subl == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
subli = subl->lv_first;
|
||||
const listitem_T *subli = tv_list_first(subl);
|
||||
if (subli == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
lnum = tv_get_number_chk(&subli->li_tv, &error);
|
||||
lnum = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error);
|
||||
if (error) {
|
||||
goto fail;
|
||||
}
|
||||
@ -5611,15 +5607,15 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
|
||||
continue;
|
||||
}
|
||||
m->pos.pos[i].lnum = lnum;
|
||||
subli = subli->li_next;
|
||||
subli = TV_LIST_ITEM_NEXT(subl, subli);
|
||||
if (subli != NULL) {
|
||||
col = tv_get_number_chk(&subli->li_tv, &error);
|
||||
col = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error);
|
||||
if (error) {
|
||||
goto fail;
|
||||
}
|
||||
subli = subli->li_next;
|
||||
subli = TV_LIST_ITEM_NEXT(subl, subli);
|
||||
if (subli != NULL) {
|
||||
len = tv_get_number_chk(&subli->li_tv, &error);
|
||||
len = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error);
|
||||
if (error) {
|
||||
goto fail;
|
||||
}
|
||||
@ -5627,12 +5623,12 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
|
||||
}
|
||||
m->pos.pos[i].col = col;
|
||||
m->pos.pos[i].len = len;
|
||||
} else if (li->li_tv.v_type == VAR_NUMBER) {
|
||||
if (li->li_tv.vval.v_number == 0) {
|
||||
--i;
|
||||
} else if (TV_LIST_ITEM_TV(li)->v_type == VAR_NUMBER) {
|
||||
if (TV_LIST_ITEM_TV(li)->vval.v_number == 0) {
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
m->pos.pos[i].lnum = li->li_tv.vval.v_number;
|
||||
m->pos.pos[i].lnum = TV_LIST_ITEM_TV(li)->vval.v_number;
|
||||
m->pos.pos[i].col = 0;
|
||||
m->pos.pos[i].len = 0;
|
||||
} else {
|
||||
@ -5645,7 +5641,11 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
|
||||
if (botlnum == 0 || lnum >= botlnum) {
|
||||
botlnum = lnum + 1;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
if (i >= MAXPOSMATCH) {
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Calculate top and bottom lines for redrawing area
|
||||
if (toplnum != 0){
|
||||
|
@ -118,6 +118,8 @@ describe('NULL', function()
|
||||
null_expr_test('does not crash setreg', 'setreg("x", L)', 0, 0)
|
||||
null_expr_test('does not crash systemlist()', 'systemlist("cat", L)', 0, {})
|
||||
null_expr_test('does not crash setline', 'setline(1, L)', 0, 0)
|
||||
null_test('does not make Neovim crash when v:oldfiles gets assigned to that', ':let v:oldfiles = L|oldfiles', 0)
|
||||
-- FIXME Add test for complete(, L)
|
||||
end)
|
||||
describe('dict', function()
|
||||
it('does not crash when indexing NULL dict', function()
|
||||
|
Loading…
Reference in New Issue
Block a user