Merge pull request #12192 from Billy4195/vim-8.2.0629

[RFC] vim-patch:8.2.0629
This commit is contained in:
Matthieu Coudron 2020-06-07 18:00:43 +02:00 committed by GitHub
commit 980b12edba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 183 additions and 102 deletions

View File

@ -1075,8 +1075,8 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
break;
case kObjectTypeBoolean:
tv->v_type = VAR_SPECIAL;
tv->vval.v_special = obj.data.boolean? kSpecialVarTrue: kSpecialVarFalse;
tv->v_type = VAR_BOOL;
tv->vval.v_bool = obj.data.boolean? kBoolVarTrue: kBoolVarFalse;
break;
case kObjectTypeBuffer:

View File

@ -213,8 +213,8 @@ static struct vimvar {
VV(VV_ERRORS, "errors", VAR_LIST, 0),
VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO),
VV(VV_EVENT, "event", VAR_DICT, VV_RO),
VV(VV_FALSE, "false", VAR_SPECIAL, VV_RO),
VV(VV_TRUE, "true", VAR_SPECIAL, VV_RO),
VV(VV_FALSE, "false", VAR_BOOL, VV_RO),
VV(VV_TRUE, "true", VAR_BOOL, VV_RO),
VV(VV_NULL, "null", VAR_SPECIAL, VV_RO),
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
@ -237,6 +237,7 @@ static struct vimvar {
// shorthand
#define vv_type vv_di.di_tv.v_type
#define vv_nr vv_di.di_tv.vval.v_number
#define vv_bool vv_di.di_tv.vval.v_bool
#define vv_special vv_di.di_tv.vval.v_special
#define vv_float vv_di.di_tv.vval.v_float
#define vv_str vv_di.di_tv.vval.v_string
@ -388,8 +389,8 @@ void eval_init(void)
set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT);
set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL);
set_vim_var_special(VV_FALSE, kSpecialVarFalse);
set_vim_var_special(VV_TRUE, kSpecialVarTrue);
set_vim_var_bool(VV_FALSE, kBoolVarFalse);
set_vim_var_bool(VV_TRUE, kBoolVarTrue);
set_vim_var_special(VV_NULL, kSpecialVarNull);
set_vim_var_special(VV_EXITING, kSpecialVarNull);
@ -1837,12 +1838,15 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
int opt_type;
long numval;
char *stringval = NULL;
const char *s = NULL;
const char c1 = *p;
*p = NUL;
varnumber_T n = tv_get_number(tv);
const char *s = tv_get_string_chk(tv); // != NULL if number or string.
if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL) {
s = tv_get_string_chk(tv); // != NULL if number or string.
}
if (s != NULL && op != NULL && *op != '=') {
opt_type = get_option_value(arg, &numval, (char_u **)&stringval,
opt_flags);
@ -1868,7 +1872,8 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
}
}
}
if (s != NULL) {
if (s != NULL || tv->v_type == VAR_BOOL
|| tv->v_type == VAR_SPECIAL) {
set_option_value((const char *)arg, n, s, opt_flags);
arg_end = (char_u *)p;
}
@ -4199,6 +4204,7 @@ eval_index(
}
return FAIL;
}
case VAR_BOOL:
case VAR_SPECIAL: {
if (verbose) {
EMSG(_("E909: Cannot index a special variable"));
@ -4420,6 +4426,7 @@ eval_index(
*rettv = var1;
break;
}
case VAR_BOOL:
case VAR_SPECIAL:
case VAR_FUNC:
case VAR_FLOAT:
@ -5273,6 +5280,7 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
break;
case VAR_UNKNOWN:
case VAR_BOOL:
case VAR_SPECIAL:
case VAR_FLOAT:
case VAR_NUMBER:
@ -5743,11 +5751,11 @@ int assert_bool(typval_T *argvars, bool is_true)
if ((argvars[0].v_type != VAR_NUMBER
|| (tv_get_number_chk(&argvars[0], &error) == 0) == is_true
|| error)
&& (argvars[0].v_type != VAR_SPECIAL
|| (argvars[0].vval.v_special
!= (SpecialVarValue) (is_true
? kSpecialVarTrue
: kSpecialVarFalse)))) {
&& (argvars[0].v_type != VAR_BOOL
|| (argvars[0].vval.v_bool
!= (BoolVarValue)(is_true
? kBoolVarTrue
: kBoolVarFalse)))) {
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[1],
(char_u *)(is_true ? "True" : "False"),
@ -8049,6 +8057,17 @@ void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
vimvars[idx].vv_nr = val;
}
/// Set boolean v: {true, false} to the given value
///
/// @param[in] idx Index of variable to set.
/// @param[in] val Value to set to.
void set_vim_var_bool(const VimVarIndex idx, const BoolVarValue val)
{
tv_clear(&vimvars[idx].vv_tv);
vimvars[idx].vv_type = VAR_BOOL;
vimvars[idx].vv_bool = val;
}
/// Set special v: variable to the given value
///
/// @param[in] idx Index of variable to set.
@ -9143,6 +9162,7 @@ int var_item_copy(const vimconv_T *const conv,
case VAR_FLOAT:
case VAR_FUNC:
case VAR_PARTIAL:
case VAR_BOOL:
case VAR_SPECIAL:
tv_copy(from, to);
break;

View File

@ -795,9 +795,9 @@ json_decode_string_cycle_start:
}
p += 3;
POP(((typval_T) {
.v_type = VAR_SPECIAL,
.v_type = VAR_BOOL,
.v_lock = VAR_UNLOCKED,
.vval = { .v_special = kSpecialVarTrue },
.vval = { .v_bool = kBoolVarTrue },
}), false);
break;
}
@ -808,9 +808,9 @@ json_decode_string_cycle_start:
}
p += 4;
POP(((typval_T) {
.v_type = VAR_SPECIAL,
.v_type = VAR_BOOL,
.v_lock = VAR_UNLOCKED,
.vval = { .v_special = kSpecialVarFalse },
.vval = { .v_bool = kBoolVarFalse },
}), false);
break;
}
@ -954,10 +954,10 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
}
case MSGPACK_OBJECT_BOOLEAN: {
*rettv = (typval_T) {
.v_type = VAR_SPECIAL,
.v_type = VAR_BOOL,
.v_lock = VAR_UNLOCKED,
.vval = {
.v_special = mobj.via.boolean ? kSpecialVarTrue : kSpecialVarFalse
.v_bool = mobj.via.boolean ? kBoolVarTrue : kBoolVarFalse
},
};
break;

View File

@ -34,10 +34,13 @@
#define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b))
#define utf_char2len(b) ((size_t)utf_char2len(b))
const char *const encode_bool_var_names[] = {
[kBoolVarTrue] = "true",
[kBoolVarFalse] = "false",
};
const char *const encode_special_var_names[] = {
[kSpecialVarNull] = "null",
[kSpecialVarTrue] = "true",
[kSpecialVarFalse] = "false",
};
#ifdef INCLUDE_GENERATED_DECLARATIONS

View File

@ -55,6 +55,7 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list)
}
/// Array mapping values from SpecialVarValue enum to names
extern const char *const encode_bool_var_names[];
extern const char *const encode_special_var_names[];
/// First codepoint in high surrogates block

View File

@ -28,11 +28,13 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
{
// 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) {
if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
&& tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL) {
switch (tv1->v_type) {
case VAR_DICT:
case VAR_FUNC:
case VAR_PARTIAL:
case VAR_BOOL:
case VAR_SPECIAL: {
break;
}

View File

@ -175,8 +175,8 @@ static int non_zero_arg(typval_T *argvars)
{
return ((argvars[0].v_type == VAR_NUMBER
&& argvars[0].vval.v_number != 0)
|| (argvars[0].v_type == VAR_SPECIAL
&& argvars[0].vval.v_special == kSpecialVarTrue)
|| (argvars[0].v_type == VAR_BOOL
&& argvars[0].vval.v_bool == kBoolVarTrue)
|| (argvars[0].v_type == VAR_STRING
&& argvars[0].vval.v_string != NULL
&& *argvars[0].vval.v_string != NUL));
@ -1758,21 +1758,23 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = (tv_dict_len(argvars[0].vval.v_dict) == 0);
break;
}
case VAR_SPECIAL: {
// Using switch to get warning if SpecialVarValue receives more values.
switch (argvars[0].vval.v_special) {
case kSpecialVarTrue: {
case VAR_BOOL: {
switch (argvars[0].vval.v_bool) {
case kBoolVarTrue: {
n = false;
break;
}
case kSpecialVarFalse:
case kSpecialVarNull: {
case kBoolVarFalse: {
n = true;
break;
}
}
break;
}
case VAR_SPECIAL: {
n = argvars[0].vval.v_special == kSpecialVarNull;
break;
}
case VAR_UNKNOWN: {
internal_error("f_empty(UNKNOWN)");
break;
@ -5189,6 +5191,7 @@ static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
}
case VAR_UNKNOWN:
case VAR_BOOL:
case VAR_SPECIAL:
case VAR_FLOAT:
case VAR_PARTIAL:
@ -10808,20 +10811,8 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
case VAR_LIST: n = VAR_TYPE_LIST; break;
case VAR_DICT: n = VAR_TYPE_DICT; break;
case VAR_FLOAT: n = VAR_TYPE_FLOAT; break;
case VAR_SPECIAL: {
switch (argvars[0].vval.v_special) {
case kSpecialVarTrue:
case kSpecialVarFalse: {
n = VAR_TYPE_BOOL;
break;
}
case kSpecialVarNull: {
n = 7;
break;
}
}
break;
}
case VAR_BOOL: n = VAR_TYPE_BOOL; break;
case VAR_SPECIAL:n = VAR_TYPE_SPECIAL; break;
case VAR_UNKNOWN: {
internal_error("f_type(UNKNOWN)");
break;

View File

@ -1693,21 +1693,21 @@ int tv_dict_add_float(dict_T *const d, const char *const key,
return OK;
}
/// Add a special entry to dictionary
/// Add a boolean entry to dictionary
///
/// @param[out] d Dictionary to add entry to.
/// @param[in] key Key to add.
/// @param[in] key_len Key length.
/// @param[in] val SpecialVarValue to add.
/// @param[in] val BoolVarValue to add.
///
/// @return OK in case of success, FAIL when key already exists.
int tv_dict_add_special(dict_T *const d, const char *const key,
const size_t key_len, SpecialVarValue val)
int tv_dict_add_bool(dict_T *const d, const char *const key,
const size_t key_len, BoolVarValue val)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
item->di_tv.v_type = VAR_SPECIAL;
item->di_tv.vval.v_special = val;
item->di_tv.v_type = VAR_BOOL;
item->di_tv.vval.v_bool = val;
if (tv_dict_add(d, item) == FAIL) {
tv_dict_item_free(item);
return FAIL;
@ -2013,12 +2013,15 @@ void tv_dict_alloc_ret(typval_T *const ret_tv)
#define TYPVAL_ENCODE_CONV_NIL(tv) \
do { \
tv->vval.v_special = kSpecialVarFalse; \
tv->vval.v_special = kSpecialVarNull; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
TYPVAL_ENCODE_CONV_NIL(tv)
do { \
tv->vval.v_bool = kBoolVarFalse; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
do { \
@ -2293,6 +2296,7 @@ void tv_free(typval_T *tv)
tv_dict_unref(tv->vval.v_dict);
break;
}
case VAR_BOOL:
case VAR_SPECIAL:
case VAR_NUMBER:
case VAR_FLOAT:
@ -2324,6 +2328,7 @@ void tv_copy(const typval_T *const from, typval_T *const to)
switch (from->v_type) {
case VAR_NUMBER:
case VAR_FLOAT:
case VAR_BOOL:
case VAR_SPECIAL: {
break;
}
@ -2425,6 +2430,7 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock)
case VAR_STRING:
case VAR_FUNC:
case VAR_PARTIAL:
case VAR_BOOL:
case VAR_SPECIAL: {
break;
}
@ -2588,6 +2594,9 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
const char *s2 = tv_get_string_buf(tv2, buf2);
return mb_strcmp_ic((bool)ic, s1, s2) == 0;
}
case VAR_BOOL: {
return tv1->vval.v_bool == tv2->vval.v_bool;
}
case VAR_SPECIAL: {
return tv1->vval.v_special == tv2->vval.v_special;
}
@ -2638,6 +2647,10 @@ bool tv_check_str_or_nr(const typval_T *const tv)
EMSG(_("E728: Expected a Number or a String, Dictionary found"));
return false;
}
case VAR_BOOL: {
EMSG(_("E5299: Expected a Number or a String, Boolean found"));
return false;
}
case VAR_SPECIAL: {
EMSG(_("E5300: Expected a Number or a String"));
return false;
@ -2677,6 +2690,7 @@ bool tv_check_num(const typval_T *const tv)
{
switch (tv->v_type) {
case VAR_NUMBER:
case VAR_BOOL:
case VAR_SPECIAL:
case VAR_STRING: {
return true;
@ -2721,6 +2735,7 @@ bool tv_check_str(const typval_T *const tv)
{
switch (tv->v_type) {
case VAR_NUMBER:
case VAR_BOOL:
case VAR_SPECIAL:
case VAR_STRING: {
return true;
@ -2791,8 +2806,11 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
}
return n;
}
case VAR_BOOL: {
return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
}
case VAR_SPECIAL: {
return tv->vval.v_special == kSpecialVarTrue ? 1 : 0;
return 0;
}
case VAR_UNKNOWN: {
emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
@ -2860,6 +2878,10 @@ float_T tv_get_float(const typval_T *const tv)
EMSG(_("E894: Using a Dictionary as a Float"));
break;
}
case VAR_BOOL: {
EMSG(_("E362: Using a boolean value as a Float"));
break;
}
case VAR_SPECIAL: {
EMSG(_("E907: Using a special value as a Float"));
break;
@ -2897,6 +2919,10 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
}
return "";
}
case VAR_BOOL: {
STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
return buf;
}
case VAR_SPECIAL: {
STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
return buf;

View File

@ -91,10 +91,14 @@ typedef struct dict_watcher {
bool busy; // prevent recursion if the dict is changed in the callback
} DictWatcher;
/// Bool variable values
typedef enum {
kBoolVarFalse, ///< v:false
kBoolVarTrue, ///< v:true
} BoolVarValue;
/// Special variable values
typedef enum {
kSpecialVarFalse, ///< v:false
kSpecialVarTrue, ///< v:true
kSpecialVarNull, ///< v:null
} SpecialVarValue;
@ -114,6 +118,7 @@ typedef enum {
VAR_LIST, ///< List, .v_list is used.
VAR_DICT, ///< Dictionary, .v_dict is used.
VAR_FLOAT, ///< Floating-point value, .v_float is used.
VAR_BOOL, ///< true, false
VAR_SPECIAL, ///< Special value (true, false, null), .v_special
///< is used.
VAR_PARTIAL, ///< Partial, .v_partial is used.
@ -125,6 +130,7 @@ typedef struct {
VarLockStatus v_lock; ///< Variable lock status.
union typval_vval_union {
varnumber_T v_number; ///< Number, for VAR_NUMBER.
BoolVarValue v_bool; ///< Bool value, for VAR_BOOL
SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
float_T v_float; ///< Floating-point number, for VAR_FLOAT.
char_u *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.

View File

@ -379,17 +379,22 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack));
break;
}
case VAR_BOOL: {
switch (tv->vval.v_bool) {
case kBoolVarTrue:
case kBoolVarFalse: {
TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue);
break;
}
}
break;
}
case VAR_SPECIAL: {
switch (tv->vval.v_special) {
case kSpecialVarNull: {
TYPVAL_ENCODE_CONV_NIL(tv); // -V1037
break;
}
case kSpecialVarTrue:
case kSpecialVarFalse: {
TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_special == kSpecialVarTrue);
break;
}
}
break;
}

View File

@ -432,8 +432,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
tv_dict_set_keys_readonly(dict);
// not readonly:
tv_dict_add_special(dict, S_LEN("abort"),
s->gotesc ? kSpecialVarTrue : kSpecialVarFalse);
tv_dict_add_bool(dict, S_LEN("abort"),
s->gotesc ? kBoolVarTrue : kBoolVarFalse);
try_enter(&tstate);
apply_autocmds(EVENT_CMDLINELEAVE, (char_u *)firstcbuf, (char_u *)firstcbuf,
false, curbuf);

View File

@ -286,10 +286,10 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
break;
}
case LUA_TBOOLEAN: {
cur.tv->v_type = VAR_SPECIAL;
cur.tv->vval.v_special = (lua_toboolean(lstate, -1)
? kSpecialVarTrue
: kSpecialVarFalse);
cur.tv->v_type = VAR_BOOL;
cur.tv->vval.v_bool = (lua_toboolean(lstate, -1)
? kBoolVarTrue
: kBoolVarFalse);
break;
}
case LUA_TSTRING: {

View File

@ -2740,8 +2740,8 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
tv_dict_add_str(dict, S_LEN("regname"), buf);
// Motion type: inclusive or exclusive.
tv_dict_add_special(dict, S_LEN("inclusive"),
oap->inclusive ? kSpecialVarTrue : kSpecialVarFalse);
tv_dict_add_bool(dict, S_LEN("inclusive"),
oap->inclusive ? kBoolVarTrue : kBoolVarFalse);
// Kind of operation: yank, delete, change).
buf[0] = (char)get_op_char(oap->op_type);
@ -2749,8 +2749,8 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
tv_dict_add_str(dict, S_LEN("operator"), buf);
// Selection type: visual or not.
tv_dict_add_special(dict, S_LEN("visual"),
oap->is_VIsual ? kSpecialVarTrue : kSpecialVarFalse);
tv_dict_add_bool(dict, S_LEN("visual"),
oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse);
tv_dict_set_keys_readonly(dict);
textlock++;

View File

@ -923,6 +923,6 @@ void pum_set_event_info(dict_T *dict)
tv_dict_add_float(dict, S_LEN("row"), r);
tv_dict_add_float(dict, S_LEN("col"), c);
tv_dict_add_nr(dict, S_LEN("size"), pum_size);
tv_dict_add_special(dict, S_LEN("scrollbar"),
pum_scrollbar ? kSpecialVarTrue : kSpecialVarFalse);
tv_dict_add_bool(dict, S_LEN("scrollbar"),
pum_scrollbar ? kBoolVarTrue : kBoolVarFalse);
}

View File

@ -561,3 +561,18 @@ func Test_visualbell()
set novisualbell
set belloff=all
endfunc
" Test for setting option values using v:false and v:true
func Test_opt_boolean()
set number&
set number
call assert_equal(1, &nu)
set nonu
call assert_equal(0, &nu)
let &nu = v:true
call assert_equal(1, &nu)
let &nu = v:false
call assert_equal(0, &nu)
set number&
endfunc

View File

@ -101,6 +101,7 @@ typedef enum {
#define VAR_TYPE_DICT 4
#define VAR_TYPE_FLOAT 5
#define VAR_TYPE_BOOL 6
#define VAR_TYPE_SPECIAL 7
// values for xp_context when doing command line completion

View File

@ -31,10 +31,12 @@ for _, func in ipairs({'bufname(%s)', 'bufnr(%s)', 'bufwinnr(%s)',
it('errors out when receives v:true/v:false/v:null', function()
-- Not compatible with Vim: in Vim it always results in buffer not found
-- without any error messages.
for _, var in ipairs({'v:true', 'v:false', 'v:null'}) do
eq('Vim(call):E5300: Expected a Number or a String',
for _, var in ipairs({'v:true', 'v:false'}) do
eq('Vim(call):E5299: Expected a Number or a String, Boolean found',
exc_exec('call ' .. func:format(var)))
end
eq('Vim(call):E5300: Expected a Number or a String',
exc_exec('call ' .. func:format('v:null')))
end)
it('errors out when receives invalid argument', function()
eq('Vim(call):E745: Expected a Number or a String, List found',

View File

@ -14,7 +14,7 @@ before_each(clear)
describe('sort()', function()
it('errors out when sorting special values', function()
eq('Vim(call):E907: Using a special value as a Float',
eq('Vim(call):E362: Using a boolean value as a Float',
exc_exec('call sort([v:true, v:false], "f")'))
end)
@ -30,6 +30,7 @@ describe('sort()', function()
errors[err] = true
end
eq({
['E362: Using a boolean value as a Float']=true,
['E891: Using a Funcref as a Float']=true,
['E892: Using a String as a Float']=true,
['E893: Using a List as a Float']=true,

View File

@ -11,7 +11,7 @@ before_each(clear)
describe('uniq()', function()
it('errors out when processing special values', function()
eq('Vim(call):E907: Using a special value as a Float',
eq('Vim(call):E362: Using a boolean value as a Float',
exc_exec('call uniq([v:true, v:false], "f")'))
end)

View File

@ -136,11 +136,15 @@ local function typvalt2lua_tab_init()
return
end
typvalt2lua_tab = {
[tonumber(eval.VAR_BOOL)] = function(t)
return ({
[tonumber(eval.kBoolVarFalse)] = false,
[tonumber(eval.kBoolVarTrue)] = true,
})[tonumber(t.vval.v_bool)]
end,
[tonumber(eval.VAR_SPECIAL)] = function(t)
return ({
[tonumber(eval.kSpecialVarFalse)] = false,
[tonumber(eval.kSpecialVarNull)] = nil_value,
[tonumber(eval.kSpecialVarTrue)] = true,
})[tonumber(t.vval.v_special)]
end,
[tonumber(eval.VAR_NUMBER)] = function(t)
@ -349,8 +353,8 @@ lua2typvalt = function(l, processed)
[null_list] = {'VAR_LIST', {v_list=ffi.cast('list_T*', nil)}},
[null_dict] = {'VAR_DICT', {v_dict=ffi.cast('dict_T*', nil)}},
[nil_value] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarNull}},
[true] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarTrue}},
[false] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarFalse}},
[true] = {'VAR_BOOL', {v_bool=eval.kBoolVarTrue}},
[false] = {'VAR_BOOL', {v_bool=eval.kBoolVarFalse}},
}
for k, v in pairs(special_vals) do

View File

@ -48,8 +48,7 @@ local lib = cimport('./src/nvim/eval/typval.h', './src/nvim/memory.h',
local function vimconv_alloc()
return ffi.gc(
ffi.cast('vimconv_T*', lib.xcalloc(1, ffi.sizeof('vimconv_T'))),
function(vc)
ffi.cast('vimconv_T*', lib.xcalloc(1, ffi.sizeof('vimconv_T'))), function(vc)
lib.convert_setup(vc, nil, nil)
lib.xfree(vc)
end)
@ -2838,6 +2837,7 @@ describe('typval.c', function()
{lib.VAR_FUNC, 'E729: using Funcref as a String'},
{lib.VAR_LIST, 'E730: using List as a String'},
{lib.VAR_DICT, 'E731: using Dictionary as a String'},
{lib.VAR_BOOL, nil},
{lib.VAR_SPECIAL, nil},
{lib.VAR_UNKNOWN, 'E908: using an invalid value as a String'},
}) do
@ -2868,8 +2868,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E745: Using a List as a Number', 0},
{lib.VAR_DICT, {v_dict=NULL}, 'E728: Using a Dictionary as a Number', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 1},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 0},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 1},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_number(UNKNOWN)', 0},
}) do
-- Using to_cstr, cannot free with tv_clear
@ -2897,8 +2897,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E745: Using a List as a Number', 0},
{lib.VAR_DICT, {v_dict=NULL}, 'E728: Using a Dictionary as a Number', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 1},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 0},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 1},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_number(UNKNOWN)', 0},
}) do
-- Using to_cstr, cannot free with tv_clear
@ -2931,8 +2931,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E745: Using a List as a Number', -1},
{lib.VAR_DICT, {v_dict=NULL}, 'E728: Using a Dictionary as a Number', -1},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 1},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 0},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 1},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_number(UNKNOWN)', -1},
}) do
lib.curwin.w_cursor.lnum = 46
@ -2961,8 +2961,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E893: Using a List as a Float', 0},
{lib.VAR_DICT, {v_dict=NULL}, 'E894: Using a Dictionary as a Float', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, 'E907: Using a special value as a Float', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, 'E907: Using a special value as a Float', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, 'E907: Using a special value as a Float', 0},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, 'E362: Using a boolean value as a Float', 0},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, 'E362: Using a boolean value as a Float', 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_float(UNKNOWN)', 0},
}) do
-- Using to_cstr, cannot free with tv_clear
@ -2993,8 +2993,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', ''},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', ''},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', ''},
}) do
-- Using to_cstr in place of Neovim allocated string, cannot
@ -3005,7 +3005,8 @@ describe('typval.c', function()
local ret = v[4]
eq(ret, check_emsg(function()
local res = lib.tv_get_string(tv)
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)
@ -3036,8 +3037,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', nil},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', nil},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', nil},
}) do
-- Using to_cstr, cannot free with tv_clear
@ -3047,7 +3048,8 @@ describe('typval.c', function()
local ret = v[4]
eq(ret, check_emsg(function()
local res = lib.tv_get_string_chk(tv)
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)
@ -3077,8 +3079,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', ''},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', ''},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', ''},
}) do
-- Using to_cstr, cannot free with tv_clear
@ -3089,7 +3091,8 @@ describe('typval.c', function()
eq(ret, check_emsg(function()
local buf = ffi.new('char[?]', lib.NUMBUFLEN, {0})
local res = lib.tv_get_string_buf(tv, buf)
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)
@ -3119,8 +3122,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', nil},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', nil},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
{lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', nil},
}) do
-- Using to_cstr, cannot free with tv_clear
@ -3131,7 +3134,8 @@ describe('typval.c', function()
eq(ret, check_emsg(function()
local buf = ffi.new('char[?]', lib.NUMBUFLEN, {0})
local res = lib.tv_get_string_buf_chk(tv, buf)
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)