eval: Split eval.c into smaller files

This commit is contained in:
ZyX 2016-07-26 23:16:23 +03:00
parent 18e7d55200
commit fb146e80aa
51 changed files with 2763 additions and 2327 deletions

View File

@ -2268,11 +2268,14 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
# //!< Header comment
# or they begin with multiple slashes followed by a space:
# //////// Header comment
# or they are Vim {{{ fold markers
match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
Search(r'^/$', line[commentend:]) or
Search(r'^!< ', line[commentend:]) or
Search(r'^/< ', line[commentend:]) or
Search(r'^/+ ', line[commentend:]))
Search(r'^/+ ', line[commentend:]) or
Search(r'^(?:\{{3}|\}{3})\d*(?: |$)',
line[commentend:]))
if not match:
error(filename, linenum, 'whitespace/comments', 4,
'Should have a space between // and comment')
@ -3575,7 +3578,7 @@ def main():
if __name__ == '__main__':
main()
# vim: ts=4 sts=4 sw=4
# vim: ts=4 sts=4 sw=4 foldmarker=▶,▲
# Ignore "too complex" warnings when using pymode.
# pylama:ignore=C901

View File

@ -14,6 +14,7 @@
#include "nvim/window.h"
#include "nvim/memory.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/map_defs.h"
#include "nvim/map.h"
#include "nvim/option.h"
@ -87,7 +88,7 @@ bool try_end(Error *err)
/// @param[out] err Details of an error that may have occurred
Object dict_get_value(dict_T *dict, String key, Error *err)
{
hashitem_T *hi = hash_find(&dict->dv_hashtab, (uint8_t *) key.data);
hashitem_T *hi = hash_find(&dict->dv_hashtab, (char_u *)key.data);
if (HASHITEM_EMPTY(hi)) {
api_set_error(err, Validation, _("Key not found"));
@ -177,13 +178,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del,
if (retval) {
rv = vim_to_object(&di->di_tv);
}
clear_tv(&di->di_tv);
tv_clear(&di->di_tv);
}
// Update the value
copy_tv(&tv, &di->di_tv);
// Clear the temporary variable
clear_tv(&tv);
tv_clear(&tv);
}
return rv;
@ -682,20 +683,20 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
break;
case kObjectTypeArray: {
list_T *list = list_alloc();
list_T *const list = tv_list_alloc();
for (uint32_t i = 0; i < obj.data.array.size; i++) {
Object item = obj.data.array.items[i];
listitem_T *li = listitem_alloc();
listitem_T *li = tv_list_item_alloc();
if (!object_to_vim(item, &li->li_tv, err)) {
// cleanup
listitem_free(li);
list_free(list);
tv_list_item_free(li);
tv_list_free(list);
return false;
}
list_append(list, li);
tv_list_append(list, li);
}
list->lv_refcount++;

View File

@ -22,6 +22,7 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/option.h"
#include "nvim/syntax.h"
#include "nvim/getchar.h"
@ -237,11 +238,11 @@ Object nvim_call_function(String fname, Array args, Error *err)
if (!try_end(err)) {
rv = vim_to_object(&rettv);
}
clear_tv(&rettv);
tv_clear(&rettv);
free_vim_args:
while (i > 0) {
clear_tv(&vim_args[--i]);
tv_clear(&vim_args[--i]);
}
return rv;

View File

@ -1472,7 +1472,7 @@ static inline void buf_init_changedtick(buf_T *const buf)
{
STATIC_ASSERT(sizeof("changedtick") <= sizeof(buf->changedtick_di.di_key),
"buf->changedtick_di cannot hold large enough keys");
buf->changedtick_di = (dictitem16_T) {
buf->changedtick_di = (ChangedtickDictItem) {
.di_flags = DI_FLAGS_RO|DI_FLAGS_FIX, // Must not include DI_FLAGS_ALLOC.
.di_tv = (typval_T) {
.v_type = VAR_NUMBER,

View File

@ -21,8 +21,6 @@ typedef struct {
#include "nvim/pos.h"
// for the number window-local and buffer-local options
#include "nvim/option_defs.h"
// for optional iconv support
#include "nvim/iconv.h"
// for jump list and tag stack sizes in a buffer and mark types
#include "nvim/mark_defs.h"
// for u_header_T; needs buf_T.
@ -30,7 +28,9 @@ typedef struct {
// for hashtab_T
#include "nvim/hashtab.h"
// for dict_T
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
// for proftime_T
#include "nvim/profile.h"
// for String
#include "nvim/api/private/defs.h"
// for Map(K, V)
@ -318,25 +318,6 @@ typedef struct {
String save_inputbuf;
} tasave_T;
/*
* Used for conversion of terminal I/O and script files.
*/
typedef struct {
int vc_type; /* zero or one of the CONV_ values */
int vc_factor; /* max. expansion factor */
# ifdef USE_ICONV
iconv_t vc_fd; /* for CONV_ICONV */
# endif
bool vc_fail; /* fail for invalid char, don't use '?' */
} vimconv_T;
#define CONV_NONE 0
#define CONV_TO_UTF8 1
#define CONV_9_TO_UTF8 2
#define CONV_TO_LATIN1 3
#define CONV_TO_LATIN9 4
#define CONV_ICONV 5
/*
* Structure used for mappings and abbreviations.
*/
@ -447,6 +428,10 @@ typedef struct {
char_u *b_syn_isk; // iskeyword option
} synblock_T;
/// Type used for changedtick_di member in buf_T
///
/// Primary exists so that literals of relevant type can be made.
typedef TV_DICTITEM_STRUCT(sizeof("changedtick")) ChangedtickDictItem;
#define BUF_HAS_QF_ENTRY 1
#define BUF_HAS_LL_ENTRY 2
@ -491,7 +476,7 @@ struct file_buffer {
// file has been changed and not written out.
/// Change identifier incremented for each change, including undo
#define b_changedtick changedtick_di.di_tv.vval.v_number
dictitem16_T changedtick_di; // b:changedtick dictionary item.
ChangedtickDictItem changedtick_di; // b:changedtick dictionary item.
bool b_saving; /* Set to true if we are in the middle of
saving the buffer. */
@ -735,8 +720,8 @@ struct file_buffer {
int b_bad_char; /* "++bad=" argument when edit started or 0 */
int b_start_bomb; /* 'bomb' when it was read */
dictitem_T b_bufvar; /* variable for "b:" Dictionary */
dict_T *b_vars; /* internal variables, local to buffer */
ScopeDictDictItem b_bufvar; ///< Variable for "b:" Dictionary.
dict_T *b_vars; ///< b: scope dictionary.
/* When a buffer is created, it starts without a swap file. b_may_swap is
* then set to indicate that a swap file may be opened later. It is reset
@ -824,9 +809,9 @@ struct tabpage_S {
buf_T *(tp_diffbuf[DB_COUNT]);
int tp_diff_invalid; ///< list of diffs is outdated
frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots
dictitem_T tp_winvar; ///< variable for "t:" Dictionary
dict_T *tp_vars; ///< internal variables, local to tab page
char_u *tp_localdir; ///< Absolute path of local CWD or NULL
ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
dict_T *tp_vars; ///< Internal variables, local to tab page.
char_u *tp_localdir; ///< Absolute path of local cwd or NULL.
};
/*
@ -1118,8 +1103,8 @@ struct window_S {
long w_scbind_pos;
dictitem_T w_winvar; /* variable for "w:" Dictionary */
dict_T *w_vars; /* internal variables, local to window */
ScopeDictDictItem w_winvar; ///< Variable for "w:" dictionary.
dict_T *w_vars; ///< Dictionary with w: variables.
int w_farsi; /* for the window dependent Farsi functions */

View File

@ -41,8 +41,10 @@ static bool chartab_initialized = false;
(buf)->b_chartab[(unsigned)(c) >> 6] |= (1ull << ((c) & 0x3f))
#define RESET_CHARTAB(buf, c) \
(buf)->b_chartab[(unsigned)(c) >> 6] &= ~(1ull << ((c) & 0x3f))
#define GET_CHARTAB_TAB(chartab, c) \
((chartab)[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
#define GET_CHARTAB(buf, c) \
((buf)->b_chartab[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
GET_CHARTAB_TAB((buf)->b_chartab, c)
// Table used below, see init_chartab() for an explanation
static char_u g_chartab[256];
@ -634,7 +636,7 @@ int char2cells(int c)
/// @param p
///
/// @return number of display cells.
int ptr2cells(char_u *p)
int ptr2cells(const char_u *p)
{
// For UTF-8 we need to look at more bytes if the first byte is >= 0x80.
if (*p >= 0x80) {
@ -776,6 +778,21 @@ bool vim_iswordc(int c)
return vim_iswordc_buf(c, curbuf);
}
/// Check that "c" is a keyword character
/// Letters and characters from 'iskeyword' option for given buffer.
/// For multi-byte characters mb_get_class() is used (builtin rules).
///
/// @param[in] c Character to check.
/// @param[in] chartab Buffer chartab.
bool vim_iswordc_tab(const int c, const uint64_t *const chartab)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (c >= 0x100) {
return utf_class(c) >= 2;
}
return c > 0 && c < 0x100 && GET_CHARTAB_TAB(chartab, c) != 0;
}
/// Check that "c" is a keyword character:
/// Letters and characters from 'iskeyword' option for given buffer.
/// For multi-byte characters mb_get_class() is used (builtin rules).
@ -785,10 +802,7 @@ bool vim_iswordc(int c)
bool vim_iswordc_buf(int c, buf_T *buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2)
{
if (c >= 0x100) {
return utf_class(c) >= 2;
}
return c > 0 && c < 0x100 && GET_CHARTAB(buf, c) != 0;
return vim_iswordc_tab(c, buf->b_chartab);
}
/// Just like vim_iswordc() but uses a pointer to the (multi-byte) character.

View File

@ -12,6 +12,7 @@
#include "nvim/state.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/mark.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor.c.generated.h"
@ -227,9 +228,10 @@ static int coladvance2(
}
}
/* prevent from moving onto a trail byte */
if (has_mbyte)
mb_adjustpos(curbuf, pos);
// Prevent from moving onto a trail byte.
if (has_mbyte) {
mark_mb_adjustpos(curbuf, pos);
}
if (col < wcol)
return FAIL;
@ -361,9 +363,10 @@ void check_cursor_col_win(win_T *win)
win->w_cursor.col = len;
} else {
win->w_cursor.col = len - 1;
/* Move the cursor to the head byte. */
if (has_mbyte)
mb_adjustpos(win->w_buffer, &win->w_cursor);
// Move the cursor to the head byte.
if (has_mbyte) {
mark_mb_adjustpos(win->w_buffer, &win->w_cursor);
}
}
} else if (win->w_cursor.col < 0) {
win->w_cursor.col = 0;

View File

@ -15,6 +15,7 @@
#include "nvim/cursor.h"
#include "nvim/digraph.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/farsi.h"
@ -3461,8 +3462,8 @@ expand_by_function (
matchdict = rettv.vval.v_dict;
break;
default:
/* TODO: Give error message? */
clear_tv(&rettv);
// TODO(brammool): Give error message?
tv_clear(&rettv);
break;
}
}
@ -3484,10 +3485,12 @@ expand_by_function (
ins_compl_add_dict(matchdict);
theend:
if (matchdict != NULL)
if (matchdict != NULL) {
dict_unref(matchdict);
if (matchlist != NULL)
list_unref(matchlist);
}
if (matchlist != NULL) {
tv_list_unref(matchlist);
}
}
/*

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
#include <msgpack.h>
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
#include "nvim/ascii.h"
@ -118,18 +118,18 @@ static inline int json_decoder_pop(ValuesStackItem obj,
if (last_container.container.vval.v_list->lv_len != 0
&& !obj.didcomma) {
EMSG2(_("E474: Expected comma before list item: %s"), val_location);
clear_tv(&obj.val);
tv_clear(&obj.val);
return FAIL;
}
assert(last_container.special_val == NULL);
listitem_T *obj_li = listitem_alloc();
listitem_T *obj_li = tv_list_item_alloc();
obj_li->li_tv = obj.val;
list_append(last_container.container.vval.v_list, obj_li);
tv_list_append(last_container.container.vval.v_list, obj_li);
} else if (last_container.stack_index == kv_size(*stack) - 2) {
if (!obj.didcolon) {
EMSG2(_("E474: Expected colon before dictionary value: %s"),
val_location);
clear_tv(&obj.val);
tv_clear(&obj.val);
return FAIL;
}
ValuesStackItem key = kv_pop(*stack);
@ -139,33 +139,33 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|| key.val.vval.v_string == NULL
|| *key.val.vval.v_string == NUL));
dictitem_T *obj_di = dictitem_alloc(key.val.vval.v_string);
clear_tv(&key.val);
tv_clear(&key.val);
if (dict_add(last_container.container.vval.v_dict, obj_di)
== FAIL) {
assert(false);
}
obj_di->di_tv = obj.val;
} else {
list_T *const kv_pair = list_alloc();
list_append_list(last_container.special_val, kv_pair);
listitem_T *const key_li = listitem_alloc();
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;
list_append(kv_pair, key_li);
listitem_T *const val_li = listitem_alloc();
tv_list_append(kv_pair, key_li);
listitem_T *const val_li = tv_list_item_alloc();
val_li->li_tv = obj.val;
list_append(kv_pair, val_li);
tv_list_append(kv_pair, val_li);
}
} else {
// Object with key only
if (!obj.is_special_string && obj.val.v_type != VAR_STRING) {
EMSG2(_("E474: Expected string key: %s"), *pp);
clear_tv(&obj.val);
tv_clear(&obj.val);
return FAIL;
} else if (!obj.didcomma
&& (last_container.special_val == NULL
&& (DICT_LEN(last_container.container.vval.v_dict) != 0))) {
EMSG2(_("E474: Expected comma before dictionary key: %s"), val_location);
clear_tv(&obj.val);
tv_clear(&obj.val);
return FAIL;
}
// Handle empty key and key represented as special dictionary
@ -175,14 +175,14 @@ static inline int json_decoder_pop(ValuesStackItem obj,
|| *obj.val.vval.v_string == NUL
|| dict_find(last_container.container.vval.v_dict,
obj.val.vval.v_string, -1))) {
clear_tv(&obj.val);
tv_clear(&obj.val);
// Restart
(void) kv_pop(*container_stack);
ValuesStackItem last_container_val =
kv_A(*stack, last_container.stack_index);
while (kv_size(*stack) > last_container.stack_index) {
clear_tv(&(kv_pop(*stack).val));
tv_clear(&(kv_pop(*stack).val));
}
*pp = last_container.s;
*didcomma = last_container_val.didcomma;
@ -430,7 +430,7 @@ static inline int parse_json_string(vimconv_T *const conv,
}
if (hasnul) {
typval_T obj;
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(&obj, kMPString, ((typval_T) {
.v_type = VAR_LIST,
@ -439,7 +439,7 @@ static inline int parse_json_string(vimconv_T *const conv,
}));
if (encode_list_write((void *) list, str, (size_t) (str_end - str))
== -1) {
clear_tv(&obj);
tv_clear(&obj);
goto parse_json_string_fail;
}
xfree(str);
@ -806,7 +806,7 @@ json_decode_string_cycle_start:
break;
}
case '[': {
list_T *list = list_alloc();
list_T *list = tv_list_alloc();
list->lv_refcount++;
typval_T tv = {
.v_type = VAR_LIST,
@ -827,7 +827,7 @@ json_decode_string_cycle_start:
list_T *val_list = NULL;
if (next_map_special) {
next_map_special = false;
val_list = list_alloc();
val_list = tv_list_alloc();
val_list->lv_refcount++;
create_special_dict(&tv, kMPMap, ((typval_T) {
.v_type = VAR_LIST,
@ -887,7 +887,7 @@ json_decode_string_after_cycle:
json_decode_string_fail:
ret = FAIL;
while (kv_size(stack)) {
clear_tv(&(kv_pop(stack).val));
tv_clear(&(kv_pop(stack).val));
}
json_decode_string_ret:
kv_destroy(stack);
@ -933,7 +933,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_number = (varnumber_T) mobj.via.u64 },
};
} else {
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(rettv, kMPInteger, ((typval_T) {
.v_type = VAR_LIST,
@ -941,10 +941,10 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_list = list },
}));
uint64_t n = mobj.via.u64;
list_append_number(list, 1);
list_append_number(list, (varnumber_T) ((n >> 62) & 0x3));
list_append_number(list, (varnumber_T) ((n >> 31) & 0x7FFFFFFF));
list_append_number(list, (varnumber_T) (n & 0x7FFFFFFF));
tv_list_append_number(list, 1);
tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
break;
}
@ -956,18 +956,18 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_number = (varnumber_T) mobj.via.i64 },
};
} else {
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(rettv, kMPInteger, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list },
}));
uint64_t n = -((uint64_t) mobj.via.i64);
list_append_number(list, -1);
list_append_number(list, (varnumber_T) ((n >> 62) & 0x3));
list_append_number(list, (varnumber_T) ((n >> 31) & 0x7FFFFFFF));
list_append_number(list, (varnumber_T) (n & 0x7FFFFFFF));
uint64_t n = -((uint64_t)mobj.via.i64);
tv_list_append_number(list, -1);
tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
break;
}
@ -980,7 +980,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
break;
}
case MSGPACK_OBJECT_STR: {
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(rettv, kMPString, ((typval_T) {
.v_type = VAR_LIST,
@ -1002,7 +1002,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
};
break;
}
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(rettv, kMPBinary, ((typval_T) {
.v_type = VAR_LIST,
@ -1016,7 +1016,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
break;
}
case MSGPACK_OBJECT_ARRAY: {
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
*rettv = (typval_T) {
.v_type = VAR_LIST,
@ -1024,9 +1024,9 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_list = list },
};
for (size_t i = 0; i < mobj.via.array.size; i++) {
listitem_T *const li = listitem_alloc();
listitem_T *const li = tv_list_item_alloc();
li->li_tv.v_type = VAR_UNKNOWN;
list_append(list, li);
tv_list_append(list, li);
if (msgpack_to_vim(mobj.via.array.ptr[i], &li->li_tv) == FAIL) {
return FAIL;
}
@ -1057,7 +1057,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
di->di_tv.v_type = VAR_UNKNOWN;
if (dict_add(dict, di) == FAIL) {
// Duplicate key: fallback to generic map
clear_tv(rettv);
tv_clear(rettv);
xfree(di);
goto msgpack_to_vim_generic_map;
}
@ -1067,7 +1067,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
}
break;
msgpack_to_vim_generic_map: {}
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(rettv, kMPMap, ((typval_T) {
.v_type = VAR_LIST,
@ -1075,14 +1075,14 @@ msgpack_to_vim_generic_map: {}
.vval = { .v_list = list },
}));
for (size_t i = 0; i < mobj.via.map.size; i++) {
list_T *const kv_pair = list_alloc();
list_append_list(list, kv_pair);
listitem_T *const key_li = listitem_alloc();
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;
list_append(kv_pair, key_li);
listitem_T *const val_li = listitem_alloc();
tv_list_append(kv_pair, key_li);
listitem_T *const val_li = tv_list_item_alloc();
val_li->li_tv.v_type = VAR_UNKNOWN;
list_append(kv_pair, val_li);
tv_list_append(kv_pair, val_li);
if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_li->li_tv) == FAIL) {
return FAIL;
}
@ -1093,11 +1093,11 @@ msgpack_to_vim_generic_map: {}
break;
}
case MSGPACK_OBJECT_EXT: {
list_T *const list = list_alloc();
list_T *const list = tv_list_alloc();
list->lv_refcount++;
list_append_number(list, mobj.via.ext.type);
list_T *const ext_val_list = list_alloc();
list_append_list(list, ext_val_list);
tv_list_append_number(list, mobj.via.ext.type);
list_T *const ext_val_list = tv_list_alloc();
tv_list_append_list(list, ext_val_list);
create_special_dict(rettv, kMPExt, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,

View File

@ -5,7 +5,7 @@
#include <msgpack.h>
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/decode.h.generated.h"

View File

@ -13,7 +13,7 @@
#include "nvim/eval/encode.h"
#include "nvim/buffer_defs.h" // vimconv_T
#include "nvim/eval.h"
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/garray.h"
#include "nvim/mbyte.h"
#include "nvim/message.h"
@ -45,7 +45,8 @@ const char *const encode_special_var_names[] = {
#endif
/// Msgpack callback for writing to readfile()-style list
int encode_list_write(void *data, const char *buf, size_t len)
int encode_list_write(void *const data, const char *const buf, const size_t len)
FUNC_ATTR_NONNULL_ARG(1)
{
if (len == 0) {
return 0;
@ -80,11 +81,11 @@ int encode_list_write(void *data, const char *buf, size_t len)
str = xmemdupz(line_start, line_length);
memchrsub(str, NUL, NL, line_length);
}
list_append_allocated_string(list, str);
tv_list_append_allocated_string(list, str);
line_end++;
}
if (line_end == end) {
list_append_allocated_string(list, NULL);
tv_list_append_allocated_string(list, NULL);
}
return 0;
}

114
src/nvim/eval/executor.c Normal file
View File

@ -0,0 +1,114 @@
#include "nvim/eval/typval.h"
#include "nvim/eval/executor.h"
#include "nvim/eval.h"
#include "nvim/message.h"
#include "nvim/vim.h"
#include "nvim/globals.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/executor.c.generated.h"
#endif
static char *e_letwrong = N_("E734: Wrong variable type for %s=");
char *e_listidx = N_("E684: list index out of range: %" PRId64);
/// Hanle tv1 += tv2, -=, .=
///
/// @param[in,out] tv1 First operand, modified typval.
/// @param[in] tv2 Second operand.
/// @param[in] op Used operator.
///
/// @return OK or FAIL.
int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
const char *const op)
FUNC_ATTR_NONNULL_ALL
{
// Can't do anything with a Funcref, a Dict or special value on the right.
if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
switch (tv1->v_type) {
case VAR_DICT:
case VAR_FUNC:
case VAR_PARTIAL:
case VAR_SPECIAL: {
break;
}
case VAR_LIST: {
if (*op != '+' || tv2->v_type != VAR_LIST) {
break;
}
// List += List
if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) {
tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
}
return OK;
}
case VAR_NUMBER:
case VAR_STRING: {
if (tv2->v_type == VAR_LIST) {
break;
}
if (*op == '+' || *op == '-') {
// nr += nr or nr -= nr
varnumber_T n = get_tv_number(tv1);
if (tv2->v_type == VAR_FLOAT) {
float_T f = n;
if (*op == '+') {
f += tv2->vval.v_float;
} else {
f -= tv2->vval.v_float;
}
tv_clear(tv1);
tv1->v_type = VAR_FLOAT;
tv1->vval.v_float = f;
} else {
if (*op == '+') {
n += get_tv_number(tv2);
} else {
n -= get_tv_number(tv2);
}
tv_clear(tv1);
tv1->v_type = VAR_NUMBER;
tv1->vval.v_number = n;
}
} else {
// str .= str
if (tv2->v_type == VAR_FLOAT) {
break;
}
char *s = (char *)get_tv_string(tv1);
char numbuf[NUMBUFLEN];
s = (char *)concat_str((char_u *)s,
get_tv_string_buf(tv2, (char_u *)numbuf));
tv_clear(tv1);
tv1->v_type = VAR_STRING;
tv1->vval.v_string = (char_u *)s;
}
return OK;
}
case VAR_FLOAT: {
if (*op == '.' || (tv2->v_type != VAR_FLOAT
&& tv2->v_type != VAR_NUMBER
&& tv2->v_type != VAR_STRING)) {
break;
}
const float_T f = (tv2->v_type == VAR_FLOAT
? tv2->vval.v_float
: get_tv_number(tv2));
if (*op == '+') {
tv1->vval.v_float += f;
} else {
tv1->vval.v_float -= f;
}
return OK;
}
case VAR_UNKNOWN: {
assert(false);
}
}
}
EMSG2(_(e_letwrong), op);
return FAIL;
}

9
src/nvim/eval/executor.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef NVIM_EVAL_EXECUTOR_H
#define NVIM_EVAL_EXECUTOR_H
extern char *e_listidx;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/executor.h.generated.h"
#endif
#endif // NVIM_EVAL_EXECUTOR_H

11
src/nvim/eval/gc.c Normal file
View File

@ -0,0 +1,11 @@
#include "nvim/eval/typval.h"
#include "nvim/eval/gc.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/gc.c.generated.h"
#endif
/// Head of list of all dictionaries
dict_T *gc_first_dict = NULL;
/// Head of list of all lists
list_T *gc_first_list = NULL;

12
src/nvim/eval/gc.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef NVIM_EVAL_GC_H
#define NVIM_EVAL_GC_H
#include "nvim/eval/typval.h"
extern dict_T *gc_first_dict;
extern list_T *gc_first_list;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/gc.h.generated.h"
#endif
#endif // NVIM_EVAL_GC_H

1171
src/nvim/eval/typval.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,32 @@
#ifndef NVIM_EVAL_DEFS_H
#define NVIM_EVAL_DEFS_H
#ifndef NVIM_EVAL_TYPVAL_H
#define NVIM_EVAL_TYPVAL_H
#include <limits.h>
#include <stddef.h>
#include <stdbool.h>
#include "nvim/hashtab.h"
#include "nvim/garray.h"
#include "nvim/mbyte.h"
#include "nvim/lib/queue.h"
#include "nvim/garray.h" // for garray_T
#include "nvim/profile.h" // for proftime_T
#include "nvim/pos.h" // for linenr_T
/// Type used for VimL VAR_NUMBER values
typedef int varnumber_T;
/// Type used for VimL VAR_FLOAT values
typedef double float_T;
/// Maximal possible value of varnumber_T variable
#define VARNUMBER_MAX INT_MAX
/// Mimimal possible value of varnumber_T variable
#define VARNUMBER_MIN INT_MIN
/// %d printf format specifier for varnumber_T
#define PRIdVARNUMBER "d"
typedef struct listvar_S list_T;
typedef struct dictvar_S dict_T;
typedef struct partial_S partial_T;
@ -64,35 +74,32 @@ typedef struct {
} vval; ///< Actual value.
} typval_T;
/* Values for "dv_scope". */
#define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */
#define VAR_DEF_SCOPE 2 /* l:, g: scope dictionaries: here funcrefs are not
allowed to mask existing functions */
/// Values for (struct dictvar_S).dv_scope
typedef enum {
VAR_NO_SCOPE = 0, ///< Not a scope dictionary.
VAR_SCOPE = 1, ///< Scope dictionary which requires prefix (a:, v:, …).
VAR_DEF_SCOPE = 2, ///< Scope dictionary which may be accessed without prefix
///< (l:, g:).
} ScopeType;
/*
* Structure to hold an item of a list: an internal variable without a name.
*/
/// Structure to hold an item of a list
typedef struct listitem_S listitem_T;
struct listitem_S {
listitem_T *li_next; /* next item in list */
listitem_T *li_prev; /* previous item in list */
typval_T li_tv; /* type and value of the variable */
listitem_T *li_next; ///< Next item in list.
listitem_T *li_prev; ///< Previous item in list.
typval_T li_tv; ///< Item value.
};
/*
* Struct used by those that are using an item in a list.
*/
/// Structure used by those that are using an item in a list
typedef struct listwatch_S listwatch_T;
struct listwatch_S {
listitem_T *lw_item; /* item being watched */
listwatch_T *lw_next; /* next watcher */
listitem_T *lw_item; ///< Item being watched.
listwatch_T *lw_next; ///< Next watcher.
};
/*
* Structure to hold info about a list.
*/
/// Structure to hold info about a list
struct listvar_S {
listitem_T *lv_first; ///< First item, NULL if none.
listitem_T *lv_last; ///< Last item, NULL if none.
@ -123,28 +130,41 @@ struct dictitem_S {
char_u di_key[1]; ///< key (actually longer!)
};
typedef struct dictitem_S dictitem_T;
#define TV_DICTITEM_STRUCT(KEY_LEN) \
struct { \
typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
uint8_t di_flags; /* Flags. */ \
char_u di_key[KEY_LEN]; /* NUL. */ \
}
/// A dictitem with a 16 character key (plus NUL)
struct dictitem16_S {
typval_T di_tv; ///< type and value of the variable
char_u di_flags; ///< flags (only used for variable)
char_u di_key[17]; ///< key
};
/// Structure to hold a scope dictionary
///
/// @warning Must be compatible with dictitem_T.
///
/// For use in find_var_in_ht to pretend that it found dictionary item when it
/// finds scope dictionary.
typedef TV_DICTITEM_STRUCT(1) ScopeDictDictItem;
typedef struct dictitem16_S dictitem16_T;
/// Structure to hold an item of a Dictionary
///
/// @warning Must be compatible with ScopeDictDictItem.
///
/// Also used for a variable.
typedef TV_DICTITEM_STRUCT() dictitem_T;
#define DI_FLAGS_RO 1 // "di_flags" value: read-only variable
#define DI_FLAGS_RO_SBX 2 // "di_flags" value: read-only in the sandbox
#define DI_FLAGS_FIX 4 // "di_flags" value: fixed: no :unlet or remove()
#define DI_FLAGS_LOCK 8 // "di_flags" value: locked variable
#define DI_FLAGS_ALLOC 16 // "di_flags" value: separately allocated
/// Flags for dictitem_T.di_flags
typedef enum {
DI_FLAGS_RO = 1, ///< Read-only value
DI_FLAGS_RO_SBX = 2, ///< Value, read-only in the sandbox
DI_FLAGS_FIX = 4, ///< Fixed value: cannot be :unlet or remove()d.
DI_FLAGS_LOCK = 8, ///< Locked value.
DI_FLAGS_ALLOC = 16, ///< Separately allocated.
} DictItemFlags;
/// Structure representing a Dictionary
struct dictvar_S {
VarLockStatus dv_lock; ///< Whole dictionary lock status.
char dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
ScopeType dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
///< dictionary represents a scope (i.e. g:, l: …).
int dv_refcount; ///< Reference count.
int dv_copyID; ///< ID used when recursivery traversing a value.
@ -155,7 +175,10 @@ struct dictvar_S {
QUEUE watchers; ///< Dictionary key watchers set by user code.
};
typedef int scid_T; // script ID
/// Type used for script ID
typedef int scid_T;
// Structure to hold info for a function that is currently being executed.
typedef struct funccall_S funccall_T;
// Structure to hold info for a user function.
@ -194,63 +217,26 @@ struct ufunc {
/// Maximum number of function arguments
#define MAX_FUNC_ARGS 20
#define VAR_SHORT_LEN 20 // short variable name length
#define FIXVAR_CNT 12 // number of fixed variables
// structure to hold info for a function that is currently being executed.
struct funccall_S {
ufunc_T *func; ///< function being called
int linenr; ///< next line to be executed
int returned; ///< ":return" used
struct { ///< fixed variables for arguments
dictitem_T var; ///< variable (without room for name)
char_u room[VAR_SHORT_LEN]; ///< room for the name
} fixvar[FIXVAR_CNT];
dict_T l_vars; ///< l: local function variables
dictitem_T l_vars_var; ///< variable for l: scope
dict_T l_avars; ///< a: argument variables
dictitem_T l_avars_var; ///< variable for a: scope
list_T l_varlist; ///< list for a:000
listitem_T l_listitems[MAX_FUNC_ARGS]; ///< listitems for a:000
typval_T *rettv; ///< return value
linenr_T breakpoint; ///< next line with breakpoint or zero
int dbg_tick; ///< debug_tick when breakpoint was set
int level; ///< top nesting level of executed function
proftime_T prof_child; ///< time spent in a child
funccall_T *caller; ///< calling function or NULL
int fc_refcount; ///< number of user functions that reference
// this funccal
int fc_copyID; ///< for garbage collection
garray_T fc_funcs; ///< list of ufunc_T* which keep a reference
// to "func"
};
// structure used by trans_function_name()
typedef struct {
dict_T *fd_dict; ///< Dictionary used.
char_u *fd_newkey; ///< New key in "dict" in allocated memory.
dictitem_T *fd_di; ///< Dictionary item used.
} funcdict_T;
struct partial_S {
int pt_refcount; ///< Reference count.
char_u *pt_name; ///< Function name; when NULL use pt_func->name.
ufunc_T *pt_func; ///< Function pointer; when NULL lookup function
///< with pt_name.
bool pt_auto; ///< when true the partial was created for using
///< dict.member in handle_subscript().
int pt_argc; ///< Number of arguments.
typval_T *pt_argv; ///< Arguments in allocated array.
dict_T *pt_dict; ///< Dict for "self".
int pt_refcount; ///< Reference count.
char_u *pt_name; ///< Function name; when NULL use pt_func->name.
ufunc_T *pt_func; ///< Function pointer; when NULL lookup function with
///< pt_name.
bool pt_auto; ///< When true the partial was created by using dict.member
///< in handle_subscript().
int pt_argc; ///< Number of arguments.
typval_T *pt_argv; ///< Arguments in allocated array.
dict_T *pt_dict; ///< Dict for "self".
};
// structure used for explicit stack while garbage collecting hash tables
/// Structure used for explicit stack while garbage collecting hash tables
typedef struct ht_stack_S {
hashtab_T *ht;
struct ht_stack_S *prev;
} ht_stack_T;
// structure used for explicit stack while garbage collecting lists
/// Structure used for explicit stack while garbage collecting lists
typedef struct list_stack_S {
list_T *list;
struct list_stack_S *prev;
@ -272,15 +258,28 @@ typedef struct list_stack_S {
/// Convert a hashitem pointer to a dictitem pointer
#define HI2DI(hi) HIKEY2DI((hi)->hi_key)
/// Type of assert_* check being performed
typedef enum
/// Get the number of items in a list
///
/// @param[in] l List to check.
static inline long tv_list_len(list_T *const l)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
ASSERT_EQUAL,
ASSERT_NOTEQUAL,
ASSERT_MATCH,
ASSERT_NOTMATCH,
ASSERT_INRANGE,
ASSERT_OTHER,
} assert_type_T;
if (l == NULL) {
return 0;
}
return l->lv_len;
}
#endif // NVIM_EVAL_DEFS_H
/// Empty string
///
/// Needed for hack which allows not allocating empty string and still not
/// crashing when freeing it.
extern const char *const tv_empty_string;
/// Specifies that free_unref_items() function has (not) been entered
extern bool tv_in_free_unref_items;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/typval.h.generated.h"
#endif
#endif // NVIM_EVAL_TYPVAL_H

View File

@ -242,7 +242,7 @@
#include <assert.h>
#include "nvim/lib/kvec.h"
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/encode.h"
#include "nvim/func_attr.h"
#include "nvim/eval/typval_encode.h"

View File

@ -11,7 +11,7 @@
#include <assert.h>
#include "nvim/lib/kvec.h"
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/func_attr.h"
/// Type of the stack entry

View File

@ -2958,7 +2958,7 @@ void sub_set_replacement(SubReplacementString sub)
{
xfree(old_sub.sub);
if (sub.additional_elements != old_sub.additional_elements) {
list_unref(old_sub.additional_elements);
tv_list_unref(old_sub.additional_elements);
}
old_sub = sub;
}

View File

@ -4,8 +4,8 @@
#include <stdbool.h>
#include "nvim/os/time.h"
#include "nvim/eval_defs.h"
#include "nvim/pos.h"
#include "nvim/eval/typval.h"
// flags for do_ecmd()
#define ECMD_HIDE 0x01 // don't free the current buffer

View File

@ -3698,12 +3698,12 @@ static void script_host_execute(char *name, exarg_T *eap)
uint8_t *script = script_get(eap, eap->arg);
if (!eap->skip) {
list_T *args = list_alloc();
list_T *args = tv_list_alloc();
// script
list_append_string(args, script ? script : eap->arg, -1);
tv_list_append_string(args, (const char *)(script ? script : eap->arg), -1);
// current range
list_append_number(args, (int)eap->line1);
list_append_number(args, (int)eap->line2);
tv_list_append_number(args, (int)eap->line1);
tv_list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute", args);
}
@ -3715,21 +3715,21 @@ static void script_host_execute_file(char *name, exarg_T *eap)
uint8_t buffer[MAXPATHL];
vim_FullName((char *)eap->arg, (char *)buffer, sizeof(buffer), false);
list_T *args = list_alloc();
list_T *args = tv_list_alloc();
// filename
list_append_string(args, buffer, -1);
tv_list_append_string(args, (const char *)buffer, -1);
// current range
list_append_number(args, (int)eap->line1);
list_append_number(args, (int)eap->line2);
tv_list_append_number(args, (int)eap->line1);
tv_list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute_file", args);
}
static void script_host_do_range(char *name, exarg_T *eap)
{
list_T *args = list_alloc();
list_append_number(args, (int)eap->line1);
list_append_number(args, (int)eap->line2);
list_append_string(args, eap->arg, -1);
list_T *args = tv_list_alloc();
tv_list_append_number(args, (int)eap->line1);
tv_list_append_number(args, (int)eap->line2);
tv_list_append_string(args, (const char *)eap->arg, -1);
(void)eval_call_provider(name, "do_range", args);
}

View File

@ -8416,8 +8416,8 @@ eval_vars (
*usedlen = 1;
return NULL;
}
result = list_find_str(get_vim_var_list(VV_OLDFILES),
(long)i);
result = (char_u *)tv_list_find_str(get_vim_var_list(VV_OLDFILES),
(long)i);
if (result == NULL) {
*errormsg = (char_u *)"";
return NULL;

View File

@ -1,6 +1,8 @@
/*
* ex_eval.c: functions for Ex command line for the +eval feature.
*/
// TODO(ZyX-I): move to eval/executor
/// @file ex_eval.c
///
/// Functions for Ex command line for the +eval feature.
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@ -779,7 +781,6 @@ void report_discard_pending(int pending, void *value)
*/
void ex_if(exarg_T *eap)
{
int error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
@ -800,6 +801,7 @@ void ex_if(exarg_T *eap)
1] &
CSF_ACTIVE));
bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
if (!skip && !error) {
@ -844,7 +846,6 @@ void ex_endif(exarg_T *eap)
*/
void ex_else(exarg_T *eap)
{
int error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
@ -901,6 +902,7 @@ void ex_else(exarg_T *eap)
}
if (eap->cmdidx == CMD_elseif) {
bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
/* When throwing error exceptions, we want to throw always the first
* of several errors in a row. This is what actually happens when
@ -925,7 +927,7 @@ void ex_else(exarg_T *eap)
*/
void ex_while(exarg_T *eap)
{
int error;
bool error;
int skip;
int result;
struct condstack *cstack = eap->cstack;

View File

@ -4249,7 +4249,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
GA_APPEND(char_u *, &ga, vim_strsave(li->li_tv.vval.v_string));
}
list_unref(retlist);
tv_list_unref(retlist);
*file = ga.ga_data;
*num_file = ga.ga_len;
@ -4545,7 +4545,7 @@ static inline void hist_free_entry(histentry_T *hisptr)
FUNC_ATTR_NONNULL_ALL
{
xfree(hisptr->hisstr);
list_unref(hisptr->additional_elements);
tv_list_unref(hisptr->additional_elements);
clear_hist_entry(hisptr);
}
@ -4601,7 +4601,7 @@ in_history (
history[type][last_i] = history[type][i];
last_i = i;
}
list_unref(list);
tv_list_unref(list);
history[type][i].hisnum = ++hisnum[type];
history[type][i].hisstr = str;
history[type][i].timestamp = os_time();

View File

@ -1,7 +1,7 @@
#ifndef NVIM_EX_GETLN_H
#define NVIM_EX_GETLN_H
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */

View File

@ -12,6 +12,7 @@
#include "nvim/syntax_defs.h"
#include "nvim/types.h"
#include "nvim/event/loop.h"
#include "nvim/os/os_defs.h"
#define IOSIZE (1024+1) // file I/O and sprintf buffer size
@ -21,16 +22,6 @@
# define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8
// takes 6 bytes for one cell)
// Maximum length of a file path. Make it a bit long, to stay
// on the safe side. But not too long to put on the stack.
#ifndef MAXPATHL
# ifdef MAXPATHLEN
# define MAXPATHL MAXPATHLEN
# else
# define MAXPATHL 256
# endif
#endif
#ifdef WIN32
# define _PATHSEPSTR "\\"
#else
@ -1226,11 +1217,6 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
EXTERN int ignored;
EXTERN char *ignoredp;
EXTERN bool in_free_unref_items INIT(= false);
// Used for checking if local variables or arguments used in a lambda.
EXTERN int *eval_lavars_used INIT(= NULL);
// If a msgpack-rpc channel should be started over stdin/stdout
EXTERN bool embedded_mode INIT(= false);

View File

@ -391,9 +391,10 @@ int main(int argc, char **argv)
shada_read_everything(NULL, false, true);
TIME_MSG("reading ShaDa");
}
/* It's better to make v:oldfiles an empty list than NULL. */
if (get_vim_var_list(VV_OLDFILES) == NULL)
set_vim_var_list(VV_OLDFILES, list_alloc());
// It's better to make v:oldfiles an empty list than NULL.
if (get_vim_var_list(VV_OLDFILES) == NULL) {
set_vim_var_list(VV_OLDFILES, tv_list_alloc());
}
/*
* "-q errorfile": Load the error file now.

View File

@ -1431,3 +1431,26 @@ void free_all_marks(void)
memset(&namedfm[0], 0, sizeof(namedfm));
}
#endif
/// Adjust position to point to the first byte of a multi-byte character
///
/// If it points to a tail byte it is move backwards to the head byte.
///
/// @param[in] buf Buffer to adjust position in.
/// @param[out] lp Position to adjust.
void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
FUNC_ATTR_NONNULL_ALL
{
if (lp->col > 0 || lp->coladd > 1) {
const char_u *const p = ml_get_buf(buf, lp->lnum, false);
lp->col -= (*mb_head_off)(p, p + lp->col);
// Reset "coladd" when the cursor would be on the right half of a
// double-wide character.
if (lp->coladd == 1
&& p[lp->col] != TAB
&& vim_isprintc((*mb_ptr2char)(p + lp->col))
&& ptr2cells(p + lp->col) > 1) {
lp->coladd = 0;
}
}
}

View File

@ -3,7 +3,7 @@
#include "nvim/pos.h"
#include "nvim/os/time.h"
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
/*
* marks: positions in a file

View File

@ -50,6 +50,7 @@
#include "nvim/strings.h"
#include "nvim/os/os.h"
#include "nvim/arabic.h"
#include "nvim/mark.h"
typedef struct {
int rangeStart;
@ -375,16 +376,18 @@ void remove_bom(char_u *s)
*/
int mb_get_class(const char_u *p)
{
return mb_get_class_buf(p, curbuf);
return mb_get_class_tab(p, curbuf->b_chartab);
}
int mb_get_class_buf(const char_u *p, buf_T *buf)
int mb_get_class_tab(const char_u *p, const uint64_t *const chartab)
{
if (MB_BYTE2LEN(p[0]) == 1) {
if (p[0] == NUL || ascii_iswhite(p[0]))
if (p[0] == NUL || ascii_iswhite(p[0])) {
return 0;
if (vim_iswordc_buf(p[0], buf))
}
if (vim_iswordc_tab(p[0], chartab)) {
return 2;
}
return 1;
}
return utf_class(utf_ptr2char(p));
@ -1639,38 +1642,16 @@ theend:
*/
void mb_adjust_cursor(void)
{
mb_adjustpos(curbuf, &curwin->w_cursor);
}
/*
* Adjust position "*lp" to point to the first byte of a multi-byte character.
* If it points to a tail byte it's moved backwards to the head byte.
*/
void mb_adjustpos(buf_T *buf, pos_T *lp)
{
char_u *p;
if (lp->col > 0
|| lp->coladd > 1
) {
p = ml_get_buf(buf, lp->lnum, FALSE);
lp->col -= (*mb_head_off)(p, p + lp->col);
/* Reset "coladd" when the cursor would be on the right half of a
* double-wide character. */
if (lp->coladd == 1
&& p[lp->col] != TAB
&& vim_isprintc((*mb_ptr2char)(p + lp->col))
&& ptr2cells(p + lp->col) > 1)
lp->coladd = 0;
}
mark_mb_adjustpos(curbuf, &curwin->w_cursor);
}
/// Checks and adjusts cursor column. Not mode-dependent.
/// @see check_cursor_col_win
///
/// @param win Places cursor on a valid column for this window.
void mb_check_adjust_col(win_T *win)
/// @param win_ Places cursor on a valid column for this window.
void mb_check_adjust_col(void *win_)
{
win_T *win = (win_T *)win_;
colnr_T oldcol = win->w_cursor.col;
// Column 0 is always valid.

View File

@ -3,6 +3,8 @@
#include <stdbool.h>
#include "nvim/iconv.h"
/*
* Return byte length of character that starts with byte "b".
* Returns 1 for a single-byte character.
@ -40,6 +42,27 @@
#define mb_ptr2char utf_ptr2char
#define mb_head_off utf_head_off
/// Flags for vimconv_T
typedef enum {
CONV_NONE = 0,
CONV_TO_UTF8 = 1,
CONV_9_TO_UTF8 = 2,
CONV_TO_LATIN1 = 3,
CONV_TO_LATIN9 = 4,
CONV_ICONV = 5,
} ConvFlags;
/// Structure used for string conversions
typedef struct {
int vc_type; ///< Zero or more ConvFlags.
int vc_factor; ///< Maximal expansion factor.
# ifdef USE_ICONV
iconv_t vc_fd; ///< Value for CONV_ICONV.
# endif
bool vc_fail; ///< What to do with invalid characters: if true, fail,
///< otherwise use '?'.
} vimconv_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mbyte.h.generated.h"
#endif

View File

@ -430,6 +430,19 @@ char *xstrdup(const char *str)
return xmemdupz(str, strlen(str));
}
/// strdup() wrapper
///
/// Unlike xstrdup() allocates a new empty string if it receives NULL.
char *xstrdupnul(const char *const str)
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
{
if (str == NULL) {
return xmallocz(0);
} else {
return xstrdup(str);
}
}
/// A version of memchr that starts the search at `src + len`.
///
/// Based on glibc's memrchr.

View File

@ -2465,7 +2465,7 @@ do_mouse (
&rettv, ARRAY_SIZE(argv), argv, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&doesrange, true, NULL, NULL);
clear_tv(&rettv);
tv_clear(&rettv);
break;
}
}
@ -7290,11 +7290,11 @@ static bool unadjust_for_sel(void)
pp = &curwin->w_cursor;
else
pp = &VIsual;
if (pp->coladd > 0)
--pp->coladd;
else if (pp->col > 0) {
--pp->col;
mb_adjustpos(curbuf, pp);
if (pp->coladd > 0) {
pp->coladd--;
} else if (pp->col > 0) {
pp->col--;
mark_mb_adjustpos(curbuf, pp);
} else if (pp->lnum > 1) {
--pp->lnum;
pp->col = (colnr_T)STRLEN(ml_get(pp->lnum));
@ -7829,7 +7829,7 @@ static void get_op_vcol(
// prevent from moving onto a trail byte
if (has_mbyte) {
mb_adjustpos(curwin->w_buffer, &oap->end);
mark_mb_adjustpos(curwin->w_buffer, &oap->end);
}
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);

View File

@ -2555,9 +2555,9 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
dict_T *dict = get_vim_var_dict(VV_EVENT);
// the yanked text
list_T *list = list_alloc();
list_T *list = tv_list_alloc();
for (size_t i = 0; i < reg->y_size; i++) {
list_append_string(list, reg->y_array[i], -1);
tv_list_append_string(list, (const char *)reg->y_array[i], -1);
}
list->lv_lock = VAR_FIXED;
dict_add_list(dict, "regcontents", list);
@ -4844,8 +4844,8 @@ static void *get_reg_wrap_one_line(char_u *s, int flags)
if (!(flags & kGRegList)) {
return s;
}
list_T *list = list_alloc();
list_append_string(list, NULL, -1);
list_T *list = tv_list_alloc();
tv_list_append_string(list, NULL, 0);
list->lv_first->li_tv.vval.v_string = s;
return list;
}
@ -4895,9 +4895,9 @@ void *get_reg_contents(int regname, int flags)
return NULL;
if (flags & kGRegList) {
list_T *list = list_alloc();
list_T *list = tv_list_alloc();
for (size_t i = 0; i < reg->y_size; i++) {
list_append_string(list, reg->y_array[i], -1);
tv_list_append_string(list, (const char *)reg->y_array[i], -1);
}
return list;
@ -5570,9 +5570,9 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
}
free_register(reg);
list_T *args = list_alloc();
char_u regname = (char_u)name;
list_append_string(args, &regname, 1);
list_T *const args = tv_list_alloc();
const char regname = (char)name;
tv_list_append_string(args, &regname, 1);
typval_T result = eval_call_provider("clipboard", "get", args);
@ -5584,7 +5584,8 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
goto err;
}
list_T *res = result.vval.v_list, *lines = NULL;
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) {
@ -5628,7 +5629,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
if (li->li_tv.v_type != VAR_STRING) {
goto err;
}
reg->y_array[i++] = (uint8_t *)xstrdup((char *)li->li_tv.vval.v_string);
reg->y_array[i++] = (char_u *)xstrdupnul((char *)li->li_tv.vval.v_string);
}
if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) {
@ -5686,35 +5687,39 @@ static void set_clipboard(int name, yankreg_T *reg)
return;
}
list_T *lines = list_alloc();
list_T *lines = tv_list_alloc();
for (size_t i = 0; i < reg->y_size; i++) {
list_append_string(lines, reg->y_array[i], -1);
tv_list_append_string(lines, (const char *)reg->y_array[i], -1);
}
list_T *args = list_alloc();
list_append_list(args, lines);
list_T *args = tv_list_alloc();
tv_list_append_list(args, lines);
char_u regtype;
char regtype;
switch (reg->y_type) {
case kMTLineWise:
regtype = 'V';
list_append_string(lines, (char_u*)"", 0);
break;
case kMTCharWise:
regtype = 'v';
break;
case kMTBlockWise:
regtype = 'b';
list_append_string(lines, (char_u*)"", 0);
break;
case kMTUnknown:
assert(false);
case kMTLineWise: {
regtype = 'V';
tv_list_append_string(lines, NULL, 0);
break;
}
case kMTCharWise: {
regtype = 'v';
break;
}
case kMTBlockWise: {
regtype = 'b';
tv_list_append_string(lines, NULL, 0);
break;
}
case kMTUnknown: {
assert(false);
}
}
list_append_string(args, &regtype, 1);
tv_list_append_string(args, &regtype, 1);
char_u regname = (char_u)name;
list_append_string(args, &regname, 1);
const char regname = (char)name;
tv_list_append_string(args, &regname, 1);
(void)eval_call_provider("clipboard", "set", args);
}

View File

@ -6,7 +6,7 @@
#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/types.h"
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/os/time.h"
typedef int (*Indenter)(void);

View File

@ -4003,7 +4003,7 @@ int get_errorlist(win_T *wp, int qf_idx, list_T *list)
bufnum = 0;
dict = dict_alloc();
list_append_dict(list, dict);
tv_list_append_dict(list, dict);
buf[0] = qfp->qf_type;
buf[1] = NUL;

View File

@ -3650,9 +3650,11 @@ static long regtry(bt_regprog_T *prog, colnr_T col)
*/
static int reg_prev_class(void)
{
if (reginput > regline)
return mb_get_class_buf(reginput - 1
- (*mb_head_off)(regline, reginput - 1), reg_buf);
if (reginput > regline) {
return mb_get_class_tab(reginput - 1 - (*mb_head_off)(regline,
reginput - 1),
reg_buf->b_chartab);
}
return -1;
}
@ -3918,12 +3920,13 @@ regmatch (
else if (has_mbyte) {
int this_class;
/* Get class of current and previous char (if it exists). */
this_class = mb_get_class_buf(reginput, reg_buf);
if (this_class <= 1)
status = RA_NOMATCH; /* not on a word at all */
else if (reg_prev_class() == this_class)
status = RA_NOMATCH; /* previous char is in same word */
// Get class of current and previous char (if it exists).
this_class = mb_get_class_tab(reginput, reg_buf->b_chartab);
if (this_class <= 1) {
status = RA_NOMATCH; // Not on a word at all.
} else if (reg_prev_class() == this_class) {
status = RA_NOMATCH; // Previous char is in same word.
}
} else {
if (!vim_iswordc_buf(c, reg_buf) || (reginput > regline
&& vim_iswordc_buf(reginput[-1
@ -3938,8 +3941,8 @@ regmatch (
else if (has_mbyte) {
int this_class, prev_class;
/* Get class of current and previous char (if it exists). */
this_class = mb_get_class_buf(reginput, reg_buf);
// Get class of current and previous char (if it exists).
this_class = mb_get_class_tab(reginput, reg_buf->b_chartab);
prev_class = reg_prev_class();
if (this_class == prev_class
|| prev_class == 0 || prev_class == 1)
@ -6617,7 +6620,7 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
if (eval_result != NULL) {
eval_result = vim_strsave(eval_result);
}
clear_tv(&rettv);
tv_clear(&rettv);
} else {
eval_result = eval_to_string(source + 2, NULL, true);
}
@ -6976,7 +6979,7 @@ list_T *reg_submatch_list(int no)
linenr_T slnum;
linenr_T elnum;
list_T *list;
char_u *s;
const char *s;
if (submatch_match == NULL) {
slnum = submatch_mmatch->startpos[no].lnum;
@ -6988,27 +6991,27 @@ list_T *reg_submatch_list(int no)
colnr_T scol = submatch_mmatch->startpos[no].col;
colnr_T ecol = submatch_mmatch->endpos[no].col;
list = list_alloc();
list = tv_list_alloc();
s = reg_getline_submatch(slnum) + scol;
s = (const char *)reg_getline_submatch(slnum) + scol;
if (slnum == elnum) {
list_append_string(list, s, ecol - scol);
tv_list_append_string(list, s, ecol - scol);
} else {
list_append_string(list, s, -1);
tv_list_append_string(list, s, -1);
for (int i = 1; i < elnum - slnum; i++) {
s = reg_getline_submatch(slnum + i);
list_append_string(list, s, -1);
s = (const char *)reg_getline_submatch(slnum + i);
tv_list_append_string(list, s, -1);
}
s = reg_getline_submatch(elnum);
list_append_string(list, s, ecol);
s = (const char *)reg_getline_submatch(elnum);
tv_list_append_string(list, s, ecol);
}
} else {
s = submatch_match->startp[no];
s = (const char *)submatch_match->startp[no];
if (s == NULL || submatch_match->endp[no] == NULL) {
return NULL;
}
list = list_alloc();
list_append_string(list, s, (int)(submatch_match->endp[no] - s));
list = tv_list_alloc();
tv_list_append_string(list, s, (const char *)submatch_match->endp[no] - s);
}
return list;

View File

@ -5410,7 +5410,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
int this_class;
// Get class of current and previous char (if it exists).
this_class = mb_get_class_buf(reginput, reg_buf);
this_class = mb_get_class_tab(reginput, reg_buf->b_chartab);
if (this_class <= 1) {
result = false;
} else if (reg_prev_class() == this_class) {
@ -5435,7 +5435,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
int this_class, prev_class;
// Get class of current and previous char (if it exists).
this_class = mb_get_class_buf(reginput, reg_buf);
this_class = mb_get_class_tab(reginput, reg_buf->b_chartab);
prev_class = reg_prev_class();
if (this_class == prev_class
|| prev_class == 0 || prev_class == 1) {

View File

@ -30,7 +30,7 @@
#include "nvim/ex_getln.h"
#include "nvim/search.h"
#include "nvim/regexp.h"
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/version.h"
#include "nvim/path.h"
#include "nvim/fileio.h"
@ -1223,7 +1223,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
khash_t(fnamebufs) fname_bufs = KHASH_EMPTY_TABLE(fnamebufs);
khash_t(strset) oldfiles_set = KHASH_EMPTY_TABLE(strset);
if (get_old_files && (oldfiles_list == NULL || force)) {
oldfiles_list = list_alloc();
oldfiles_list = tv_list_alloc();
set_vim_var_list(VV_OLDFILES, oldfiles_list);
}
ShaDaReadResult srni_ret;
@ -1435,8 +1435,8 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
fname = xstrdup(fname);
}
int kh_ret;
(void) kh_put(strset, &oldfiles_set, fname, &kh_ret);
list_append_allocated_string(oldfiles_list, fname);
(void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
tv_list_append_allocated_string(oldfiles_list, fname);
if (!want_marks) {
// Avoid free because this string was already used.
cur_entry.data.filemark.fname = NULL;
@ -1573,7 +1573,9 @@ static char *shada_filename(const char *file)
do { \
const String s_ = (s); \
msgpack_pack_str(spacker, s_.size); \
msgpack_pack_str_body(spacker, s_.data, s_.size); \
if (s_.size) { \
msgpack_pack_str_body(spacker, s_.data, s_.size); \
} \
} while (0)
#define PACK_BIN(s) \
do { \
@ -1965,7 +1967,7 @@ static ShaDaWriteResult shada_pack_encoded_entry(msgpack_packer *const packer,
typval_T tgttv;
var_item_copy(sd_conv, &entry.data.data.global_var.value, &tgttv,
true, 0);
clear_tv(&entry.data.data.global_var.value);
tv_clear(&entry.data.data.global_var.value);
entry.data.data.global_var.value = tgttv;
}
ret = shada_pack_entry(packer, entry.data, max_kbyte);
@ -2573,13 +2575,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
}
}, max_kbyte)) == kSDWriteFailed) {
clear_tv(&vartv);
clear_tv(&tgttv);
tv_clear(&vartv);
tv_clear(&tgttv);
ret = kSDWriteFailed;
goto shada_write_exit;
}
clear_tv(&vartv);
clear_tv(&tgttv);
tv_clear(&vartv);
tv_clear(&tgttv);
if (spe_ret == kSDWriteSuccessfull) {
int kh_ret;
(void) kh_put(strset, &wms->dumped_variables, name, &kh_ret);
@ -3172,18 +3174,18 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
break;
}
case kSDItemHistoryEntry: {
list_unref(entry->data.history_item.additional_elements);
tv_list_unref(entry->data.history_item.additional_elements);
xfree(entry->data.history_item.string);
break;
}
case kSDItemVariable: {
list_unref(entry->data.global_var.additional_elements);
tv_list_unref(entry->data.global_var.additional_elements);
xfree(entry->data.global_var.name);
clear_tv(&entry->data.global_var.value);
tv_clear(&entry->data.global_var.value);
break;
}
case kSDItemSubString: {
list_unref(entry->data.sub_string.additional_elements);
tv_list_unref(entry->data.sub_string.additional_elements);
xfree(entry->data.sub_string.sub);
break;
}
@ -3451,7 +3453,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
"cannot be converted to a VimL dictionary")), \
initial_fpos); \
ga_clear(&ad_ga); \
clear_tv(&adtv); \
tv_clear(&adtv); \
goto shada_read_next_item_error; \
} \
tgt = adtv.vval.v_dict; \
@ -3474,7 +3476,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
if (msgpack_to_vim(obj, &aetv) == FAIL) { \
emsgf(_(READERR(name, "cannot be converted to a VimL list")), \
initial_fpos); \
clear_tv(&aetv); \
tv_clear(&aetv); \
goto shada_read_next_item_error; \
} \
assert(aetv.v_type == VAR_LIST); \
@ -3866,7 +3868,7 @@ shada_read_next_item_hist_no_conv:
&tgttv,
true,
0);
clear_tv(&entry->data.global_var.value);
tv_clear(&entry->data.global_var.value);
entry->data.global_var.value = tgttv;
}
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,

View File

@ -3248,7 +3248,7 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr)
add_suggestion(su, &su->su_ga, p, su->su_badlen,
score, 0, true, su->su_sallang, false);
}
list_unref(list);
tv_list_unref(list);
}
// Remove bogus suggestions, sort and truncate at "maxcount".

View File

@ -571,7 +571,7 @@ static varnumber_T tv_nr(typval_T *tvs, int *idxp)
EMSG(_(e_printf));
} else {
(*idxp)++;
int err = false;
bool err = false;
n = (varnumber_T)get_tv_number_chk(&tvs[idx], &err);
if (err) {
n = 0;

View File

@ -5,7 +5,7 @@
#include <stdarg.h>
#include "nvim/types.h"
#include "nvim/eval_defs.h"
#include "nvim/eval/typval.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "strings.h.generated.h"

View File

@ -674,7 +674,7 @@ do_tag (
fname = xmalloc(MAXPATHL + 1);
cmd = xmalloc(CMDBUFFSIZE + 1);
list = list_alloc();
list = tv_list_alloc();
for (i = 0; i < num_matches; ++i) {
int len, cmd_len;
@ -774,7 +774,7 @@ do_tag (
}
dict = dict_alloc();
list_append_dict(list, dict);
tv_list_append_dict(list, dict);
dict_add_nr_str(dict, "text", 0L, tag_name);
dict_add_nr_str(dict, "filename", 0L, fname);
@ -786,7 +786,7 @@ do_tag (
vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
set_errorlist(curwin, list, ' ', IObuff, NULL);
list_free(list);
tv_list_free(list);
xfree(fname);
xfree(cmd);
@ -2825,7 +2825,7 @@ int get_tags(list_T *list, char_u *pat)
continue;
dict = dict_alloc();
list_append_dict(list, dict);
tv_list_append_dict(list, dict);
full_fname = tag_full_fname(&tp);
if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL

View File

@ -2952,14 +2952,14 @@ void u_eval_tree(u_header_T *first_uhp, list_T *list)
dict_add_nr_str(dict, "save", uhp->uh_save_nr, NULL);
if (uhp->uh_alt_next.ptr != NULL) {
list_T *alt_list = list_alloc();
list_T *alt_list = tv_list_alloc();
/* Recursive call to add alternate undo tree. */
u_eval_tree(uhp->uh_alt_next.ptr, alt_list);
dict_add_list(dict, "alt", alt_list);
}
list_append_dict(list, dict);
tv_list_append_dict(list, dict);
uhp = uhp->uh_prev.ptr;
}
}

View File

@ -5582,7 +5582,7 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
int len = 1;
list_T *subl;
listitem_T *subli;
int error = false;
bool error = false;
if (li->li_tv.v_type == VAR_LIST) {
subl = li->li_tv.vval.v_list;
@ -5594,7 +5594,7 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
goto fail;
}
lnum = get_tv_number_chk(&subli->li_tv, &error);
if (error == true) {
if (error) {
goto fail;
}
if (lnum == 0) {
@ -5605,12 +5605,13 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
subli = subli->li_next;
if (subli != NULL) {
col = get_tv_number_chk(&subli->li_tv, &error);
if (error == true)
if (error) {
goto fail;
}
subli = subli->li_next;
if (subli != NULL) {
len = get_tv_number_chk(&subli->li_tv, &error);
if (error == true) {
if (error) {
goto fail;
}
}
@ -5881,8 +5882,8 @@ void win_id2tabwin(typval_T *argvars, list_T *list)
int id = get_tv_number(&argvars[0]);
win_get_tabwin(id, &tabnr, &winnr);
list_append_number(list, tabnr);
list_append_number(list, winnr);
tv_list_append_number(list, tabnr);
tv_list_append_number(list, winnr);
}
win_T * win_id2wp(typval_T *argvars)
@ -5918,7 +5919,7 @@ void win_findbuf(typval_T *argvars, list_T *list)
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer->b_fnum == bufnr) {
list_append_number(list, wp->handle);
tv_list_append_number(list, wp->handle);
}
}
}

View File

@ -7,7 +7,7 @@ local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
local decode = cimport('./src/nvim/eval/decode.h', './src/nvim/eval_defs.h',
local decode = cimport('./src/nvim/eval/decode.h', './src/nvim/eval/typval.h',
'./src/nvim/globals.h', './src/nvim/memory.h',
'./src/nvim/message.h')

View File

@ -5,7 +5,7 @@ local to_cstr = helpers.to_cstr
local ffi = helpers.ffi
local eq = helpers.eq
local eval = cimport('./src/nvim/eval.h', './src/nvim/eval_defs.h',
local eval = cimport('./src/nvim/eval.h', './src/nvim/eval/typval.h',
'./src/nvim/hashtab.h')
local null_string = {[true]='NULL string'}
@ -33,7 +33,7 @@ local function li_alloc(nogc)
end
local function list(...)
local ret = ffi.gc(eval.list_alloc(), eval.list_unref)
local ret = ffi.gc(eval.tv_list_alloc(), eval.tv_list_unref)
eq(0, ret.lv_refcount)
ret.lv_refcount = 1
for i = 1, select('#', ...) do
@ -241,7 +241,7 @@ local typvalt = function(typ, vval)
elseif type(typ) == 'string' then
typ = eval[typ]
end
return ffi.gc(ffi.new('typval_T', {v_type=typ, vval=vval}), eval.clear_tv)
return ffi.gc(ffi.new('typval_T', {v_type=typ, vval=vval}), eval.tv_clear)
end
local lua2typvalt_type_tab = {
@ -256,14 +256,14 @@ local lua2typvalt_type_tab = {
processed[l].lv_refcount = processed[l].lv_refcount + 1
return typvalt(eval.VAR_LIST, {v_list=processed[l]})
end
local lst = eval.list_alloc()
local lst = eval.tv_list_alloc()
lst.lv_refcount = 1
processed[l] = lst
local ret = typvalt(eval.VAR_LIST, {v_list=lst})
for i = 1, #l do
local item_tv = ffi.gc(lua2typvalt(l[i], processed), nil)
eval.list_append_tv(lst, item_tv)
eval.clear_tv(item_tv)
eval.tv_list_append_tv(lst, item_tv)
eval.tv_clear(item_tv)
end
return ret
end,
@ -281,7 +281,7 @@ local lua2typvalt_type_tab = {
local di = eval.dictitem_alloc(to_cstr(k))
local val_tv = ffi.gc(lua2typvalt(v, processed), nil)
eval.copy_tv(val_tv, di.di_tv)
eval.clear_tv(val_tv)
eval.tv_clear(val_tv)
eval.dict_add(dct, di)
end
end
@ -301,7 +301,7 @@ local lua2typvalt_type_tab = {
for i, arg in ipairs(l.args) do
local arg_tv = ffi.gc(lua2typvalt(arg, processed), nil)
eval.copy_tv(arg_tv, argv[i - 1])
eval.clear_tv(arg_tv)
eval.tv_clear(arg_tv)
end
end
local dict = nil

View File

@ -10,7 +10,7 @@ local eval = cimport('./src/nvim/eval.h', './src/nvim/memory.h')
local eval_expr = function(expr)
return ffi.gc(eval.eval_expr(to_cstr(expr), nil), function(tv)
eval.clear_tv(tv)
eval.tv_clear(tv)
eval.xfree(tv)
end)
end

View File

@ -14,7 +14,7 @@ local list_items = eval_helpers.list_items
local dict_items = eval_helpers.dict_items
local lua2typvalt = eval_helpers.lua2typvalt
local lib = cimport('./src/nvim/eval_defs.h', './src/nvim/eval.h')
local lib = cimport('./src/nvim/eval/typval.h', './src/nvim/eval.h')
local alloc_log = alloc_log_new()
@ -26,7 +26,7 @@ after_each(function()
alloc_log:after_each()
end)
describe('clear_tv()', function()
describe('tv_clear()', function()
itp('successfully frees all lists in [&l [1], *l, *l]', function()
local l_inner = {1}
local list = {l_inner, l_inner, l_inner}
@ -44,7 +44,7 @@ describe('clear_tv()', function()
a.li(lis[3]),
})
eq(3, list_inner_p.lv_refcount)
lib.clear_tv(list_tv)
lib.tv_clear(list_tv)
alloc_log:check({
a.freed(lis_inner[1]),
a.freed(list_inner_p),
@ -69,7 +69,7 @@ describe('clear_tv()', function()
a.li(lis[3]),
})
eq(3, list_inner_p.lv_refcount)
lib.clear_tv(list_tv)
lib.tv_clear(list_tv)
alloc_log:check({
a.freed(list_inner_p),
a.freed(lis[1]),
@ -92,7 +92,7 @@ describe('clear_tv()', function()
a.li(lis[2]),
})
eq(2, dict_inner_p.dv_refcount)
lib.clear_tv(list_tv)
lib.tv_clear(list_tv)
alloc_log:check({
a.freed(dict_inner_p),
a.freed(lis[1]),
@ -116,7 +116,7 @@ describe('clear_tv()', function()
a.li(lis[2]),
})
eq(2, dict_inner_p.dv_refcount)
lib.clear_tv(list_tv)
lib.tv_clear(list_tv)
alloc_log:check({
a.freed(dis.a),
a.freed(dict_inner_p),