diff options
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 83 |
1 files changed, 55 insertions, 28 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7179e1569c..66cd0e09c6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -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); @@ -444,7 +445,7 @@ void eval_clear(void) // unreferenced lists and dicts (void)garbage_collect(false); - // functions + // functions not garbage collected free_all_functions(); } @@ -873,17 +874,19 @@ char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert) char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox) { char_u *retval; - void *save_funccalp; + funccal_entry_T funccal_entry; - save_funccalp = save_funccal(); - if (use_sandbox) - ++sandbox; - ++textlock; - retval = eval_to_string(arg, nextcmd, FALSE); - if (use_sandbox) - --sandbox; - --textlock; - restore_funccal(save_funccalp); + save_funccal(&funccal_entry); + if (use_sandbox) { + sandbox++; + } + textlock++; + retval = eval_to_string(arg, nextcmd, false); + if (use_sandbox) { + sandbox--; + } + textlock--; + restore_funccal(); return retval; } @@ -1835,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); @@ -1866,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; } @@ -4197,6 +4204,7 @@ eval_index( } return FAIL; } + case VAR_BOOL: case VAR_SPECIAL: { if (verbose) { EMSG(_("E909: Cannot index a special variable")); @@ -4418,6 +4426,7 @@ eval_index( *rettv = var1; break; } + case VAR_BOOL: case VAR_SPECIAL: case VAR_FUNC: case VAR_FLOAT: @@ -5026,7 +5035,7 @@ bool garbage_collect(bool testing) // 3. Check if any funccal can be freed now. // This may call us back recursively. - did_free = did_free || free_unref_funccal(copyID, testing); + did_free = free_unref_funccal(copyID, testing) || did_free; } else if (p_verbose > 0) { verb_msg(_( "Not enough memory to set references, garbage collection aborted!")); @@ -5271,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: @@ -5741,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"), @@ -6118,7 +6128,7 @@ void common_function(typval_T *argvars, typval_T *rettv, if (tv_list_len(list) == 0) { arg_idx = 0; } else if (tv_list_len(list) > MAX_FUNC_ARGS) { - emsg_funcname((char *)e_toomanyarg, name); + emsg_funcname((char *)e_toomanyarg, s); xfree(name); goto theend; } @@ -6752,6 +6762,7 @@ void mapblock_fill_dict(dict_T *const dict, } tv_dict_add_allocated_str(dict, S_LEN("lhs"), lhs); tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value); + tv_dict_add_nr(dict, S_LEN("script"), mp->m_noremap == REMAP_SCRIPT ? 1 : 0); tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0); tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0); tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ctx.sc_sid); @@ -8046,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. @@ -9140,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; @@ -9766,9 +9789,11 @@ const void *var_shada_iter(const void *const iter, const char **const name, void var_set_global(const char *const name, typval_T vartv) { - funccall_T *const saved_funccal = (funccall_T *)save_funccal(); + funccal_entry_T funccall_entry; + + save_funccal(&funccall_entry); set_var(name, strlen(name), &vartv, false); - restore_funccal(saved_funccal); + restore_funccal(); } int store_session_globals(FILE *fd) @@ -10324,8 +10349,10 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments) .autocmd_fname = autocmd_fname, .autocmd_match = autocmd_match, .autocmd_bufnr = autocmd_bufnr, - .funccalp = save_funccal() + .funccalp = (void *)get_current_funccal() }; + funccal_entry_T funccal_entry; + save_funccal(&funccal_entry); provider_call_nesting++; typval_T argvars[3] = { @@ -10352,7 +10379,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments) tv_list_unref(arguments); // Restore caller scope information - restore_funccal(provider_caller_scope.funccalp); + restore_funccal(); provider_caller_scope = saved_provider_caller_scope; provider_call_nesting--; assert(provider_call_nesting >= 0); |