diff options
Diffstat (limited to 'src/nvim/eval.c')
| -rw-r--r-- | src/nvim/eval.c | 966 |
1 files changed, 278 insertions, 688 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7cb8bdee19..53f1074033 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1,9 +1,7 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -/* - * eval.c: Expression evaluation. - */ +// eval.c: Expression evaluation. #include <math.h> #include <stdlib.h> @@ -15,10 +13,12 @@ #endif #include "nvim/ascii.h" +#include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/channel.h" #include "nvim/charset.h" +#include "nvim/cmdhist.h" #include "nvim/cursor.h" #include "nvim/edit.h" #include "nvim/eval.h" @@ -29,9 +29,10 @@ #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" #include "nvim/ex_cmds2.h" +#include "nvim/ex_docmd.h" +#include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/ex_session.h" -#include "nvim/fileio.h" #include "nvim/getchar.h" #include "nvim/highlight_group.h" #include "nvim/lua/executor.h" @@ -43,8 +44,10 @@ #include "nvim/os/input.h" #include "nvim/os/shell.h" #include "nvim/path.h" +#include "nvim/profile.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" +#include "nvim/runtime.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/sign.h" @@ -71,19 +74,15 @@ static char * const namespace_char = "abglstvw"; /// Variable used for g: static ScopeDictDictItem globvars_var; -/* - * Old Vim variables such as "v:version" are also available without the "v:". - * Also in functions. We need a special hashtable for them. - */ +/// Old Vim variables such as "v:version" are also available without the "v:". +/// Also in functions. We need a special hashtable for them. static hashtab_T compat_hashtab; /// Used for checking if local variables or arguments used in a lambda. bool *eval_lavars_used = NULL; -/* - * Array to hold the hashtab with variables local to each sourced script. - * Each item holds a variable (nameless) that points to the dict_T. - */ +/// Array to hold the hashtab with variables local to each sourced script. +/// Each item holds a variable (nameless) that points to the dict_T. typedef struct { ScopeDictDictItem sv_var; dict_T sv_dict; @@ -98,9 +97,7 @@ static int echo_attr = 0; // attributes used for ":echo" // The names of packages that once were loaded are remembered. static garray_T ga_loaded = { 0, 0, sizeof(char *), 4, NULL }; -/* - * Info used by a ":for" loop. - */ +/// Info used by a ":for" loop. typedef struct { int fi_semicolon; // TRUE if ending in '; var]' int fi_varcount; // nr of variables in the list @@ -356,8 +353,6 @@ void eval_init(void) { vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; - struct vimvar *p; - init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); vimvardict.dv_lock = VAR_FIXED; @@ -365,7 +360,7 @@ void eval_init(void) func_init(); for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) { - p = &vimvars[i]; + struct vimvar *p = &vimvars[i]; assert(STRLEN(p->vv_name) <= VIMVAR_KEY_LEN); STRCPY(p->vv_di.di_key, p->vv_name); if (p->vv_flags & VV_RO) { @@ -447,10 +442,8 @@ void eval_init(void) #if defined(EXITFREE) void eval_clear(void) { - struct vimvar *p; - for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) { - p = &vimvars[i]; + struct vimvar *p = &vimvars[i]; if (p->vv_di.di_tv.v_type == VAR_STRING) { XFREE_CLEAR(p->vv_str); } else if (p->vv_di.di_tv.v_type == VAR_LIST) { @@ -473,13 +466,13 @@ void eval_clear(void) // autoloaded script names ga_clear_strings(&ga_loaded); - /* Script-local variables. First clear all the variables and in a second - * loop free the scriptvar_T, because a variable in one script might hold - * a reference to the whole scope of another script. */ - for (int i = 1; i <= ga_scripts.ga_len; ++i) { + // Script-local variables. First clear all the variables and in a second + // loop free the scriptvar_T, because a variable in one script might hold + // a reference to the whole scope of another script. + for (int i = 1; i <= ga_scripts.ga_len; i++) { vars_clear(&SCRIPT_VARS(i)); } - for (int i = 1; i <= ga_scripts.ga_len; ++i) { + for (int i = 1; i <= ga_scripts.ga_len; i++) { xfree(SCRIPT_SV(i)); } ga_clear(&ga_scripts); @@ -518,10 +511,6 @@ static char *redir_varname = NULL; /// @return OK if successfully completed the setup. FAIL otherwise. int var_redir_start(char *name, int append) { - int save_emsg; - int err; - typval_T tv; - // Catch a bad name early. if (!eval_isnamec1(*name)) { emsg(_(e_invarg)); @@ -553,10 +542,11 @@ int var_redir_start(char *name, int append) return FAIL; } - /* check if we can write to the variable: set it to or append an empty - * string */ - save_emsg = did_emsg; - did_emsg = FALSE; + // check if we can write to the variable: set it to or append an empty + // string + int save_emsg = did_emsg; + did_emsg = false; + typval_T tv; tv.v_type = VAR_STRING; tv.vval.v_string = ""; if (append) { @@ -565,7 +555,7 @@ int var_redir_start(char *name, int append) set_var_lval(redir_lval, redir_endp, &tv, true, false, "="); } clear_lval(redir_lval); - err = did_emsg; + int err = did_emsg; did_emsg |= save_emsg; if (err) { redir_endp = NULL; // don't store a value, only cleanup @@ -585,12 +575,11 @@ int var_redir_start(char *name, int append) /// :redir END void var_redir_str(char *value, int value_len) { - int len; - if (redir_lval == NULL) { return; } + int len; if (value_len == -1) { len = (int)STRLEN(value); // Append the entire string } else { @@ -606,12 +595,11 @@ void var_redir_str(char *value, int value_len) /// Frees the allocated memory. void var_redir_stop(void) { - typval_T tv; - if (redir_lval != NULL) { // If there was no error: assign the text to the variable. if (redir_endp != NULL) { ga_append(&redir_ga, NUL); // Append the trailing NUL. + typval_T tv; tv.v_type = VAR_STRING; tv.vval.v_string = redir_ga.ga_data; // Call get_lval() again, if it's inside a Dict or List it may @@ -935,7 +923,7 @@ varnumber_T eval_to_number(char *expr) varnumber_T retval; char *p = skipwhite(expr); - ++emsg_off; + emsg_off++; if (eval1(&p, &rettv, true) == FAIL) { retval = -1; @@ -943,7 +931,7 @@ varnumber_T eval_to_number(char *expr) retval = tv_get_number_chk(&rettv, NULL); tv_clear(&rettv); } - --emsg_off; + emsg_off--; return retval; } @@ -1000,11 +988,9 @@ void prepare_vimvar(int idx, typval_T *save_tv) /// When no longer defined, remove the variable from the v: hashtable. void restore_vimvar(int idx, typval_T *save_tv) { - hashitem_T *hi; - vimvars[idx].vv_tv = *save_tv; if (vimvars[idx].vv_type == VAR_UNKNOWN) { - hi = hash_find(&vimvarht, (char *)vimvars[idx].vv_di.di_key); + hashitem_T *hi = hash_find(&vimvarht, (char *)vimvars[idx].vv_di.di_key); if (HASHITEM_EMPTY(hi)) { internal_error("restore_vimvar()"); } else { @@ -1040,7 +1026,7 @@ list_T *eval_spell_expr(char *badword, char *expr) vimvars[VV_VAL].vv_type = VAR_STRING; vimvars[VV_VAL].vv_str = badword; if (p_verbose == 0) { - ++emsg_off; + emsg_off++; } if (eval1(&p, &rettv, true) == OK) { @@ -1052,7 +1038,7 @@ list_T *eval_spell_expr(char *badword, char *expr) } if (p_verbose == 0) { - --emsg_off; + emsg_off--; } restore_vimvar(VV_VAL, &save_val); @@ -1134,12 +1120,11 @@ varnumber_T call_func_retnr(const char *func, int argc, typval_T *argv) FUNC_ATTR_NONNULL_ALL { typval_T rettv; - varnumber_T retval; if (call_vim_function((char *)func, argc, argv, &rettv) == FAIL) { return -1; } - retval = tv_get_number_chk(&rettv, NULL); + varnumber_T retval = tv_get_number_chk(&rettv, NULL); tv_clear(&rettv); return retval; } @@ -1191,42 +1176,6 @@ void *call_func_retlist(const char *func, int argc, typval_T *argv) return rettv.vval.v_list; } -/// Prepare profiling for entering a child or something else that is not -/// counted for the script/function itself. -/// Should always be called in pair with prof_child_exit(). -/// -/// @param tm place to store waittime -void prof_child_enter(proftime_T *tm) -{ - funccall_T *fc = get_current_funccal(); - - if (fc != NULL && fc->func->uf_profiling) { - fc->prof_child = profile_start(); - } - - script_prof_save(tm); -} - -/// Take care of time spent in a child. -/// Should always be called after prof_child_enter(). -/// -/// @param tm where waittime was stored -void prof_child_exit(proftime_T *tm) -{ - funccall_T *fc = get_current_funccal(); - - if (fc != NULL && fc->func->uf_profiling) { - fc->prof_child = profile_end(fc->prof_child); - // don't count waiting time - fc->prof_child = profile_sub_wait(*tm, fc->prof_child); - fc->func->uf_tm_children = - profile_add(fc->func->uf_tm_children, fc->prof_child); - fc->func->uf_tml_children = - profile_add(fc->func->uf_tml_children, fc->prof_child); - } - script_prof_restore(tm); -} - /// Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding /// it in "*cp". Doesn't give error messages. int eval_foldexpr(char *arg, int *cp) @@ -1235,11 +1184,11 @@ int eval_foldexpr(char *arg, int *cp) varnumber_T retval; int use_sandbox = was_set_insecurely(curwin, "foldexpr", OPT_LOCAL); - ++emsg_off; + emsg_off++; if (use_sandbox) { - ++sandbox; + sandbox++; } - ++textlock; + textlock++; *cp = NUL; if (eval0(arg, &tv, NULL, true) == FAIL) { retval = 0; @@ -1260,11 +1209,11 @@ int eval_foldexpr(char *arg, int *cp) } tv_clear(&tv); } - --emsg_off; + emsg_off--; if (use_sandbox) { - --sandbox; + sandbox--; } - --textlock; + textlock--; return (int)retval; } @@ -1298,16 +1247,11 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const const bool skip, const int flags, const int fne_flags) FUNC_ATTR_NONNULL_ARG(1, 3) { - dictitem_T *v; - typval_T var1; - typval_T var2; - int empty1 = FALSE; - listitem_T *ni; - hashtab_T *ht = NULL; + bool empty1 = false; int quiet = flags & GLV_QUIET; // Clear everything in "lp". - memset(lp, 0, sizeof(lval_T)); + CLEAR_POINTER(lp); if (skip) { // When skipping just find the end of the name. @@ -1355,11 +1299,13 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const return p; } + hashtab_T *ht = NULL; + // Only pass &ht when we would write to the variable, it prevents autoload // as well. - v = find_var(lp->ll_name, lp->ll_name_len, - (flags & GLV_READ_ONLY) ? NULL : &ht, - flags & GLV_NO_AUTOLOAD); + dictitem_T *v = find_var(lp->ll_name, lp->ll_name_len, + (flags & GLV_READ_ONLY) ? NULL : &ht, + flags & GLV_NO_AUTOLOAD); if (v == NULL && !quiet) { semsg(_("E121: Undefined variable: %.*s"), (int)lp->ll_name_len, lp->ll_name); @@ -1370,7 +1316,9 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const // Loop until no more [idx] or .key is following. lp->ll_tv = &v->di_tv; + typval_T var1; var1.v_type = VAR_UNKNOWN; + typval_T var2; var2.v_type = VAR_UNKNOWN; while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) { if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) @@ -1612,7 +1560,7 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const lp->ll_n2 = (long)tv_get_number(&var2); // Is number or string. tv_clear(&var2); if (lp->ll_n2 < 0) { - ni = tv_list_find(lp->ll_list, (int)lp->ll_n2); + listitem_T *ni = tv_list_find(lp->ll_list, (int)lp->ll_n2); if (ni == NULL) { if (!quiet) { semsg(_(e_listidx), (int64_t)lp->ll_n2); @@ -1765,9 +1713,7 @@ void set_var_lval(lval_T *lp, char *endp, typval_T *rettv, int copy, const bool ll_n1++; } - /* - * Assign the List values to the list items. - */ + // Assign the List values to the list items. for (ri = tv_list_first(rettv->vval.v_list); ri != NULL;) { if (op != NULL && *op != '=') { eexe_mod_op(TV_LIST_ITEM_TV(lp->ll_li), TV_LIST_ITEM_TV(ri), op); @@ -1888,7 +1834,7 @@ void *eval_for_line(const char *arg, bool *errp, char **nextcmdp, int skip) } if (skip) { - ++emsg_skip; + emsg_skip++; } if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) { *errp = false; @@ -1930,7 +1876,7 @@ void *eval_for_line(const char *arg, bool *errp, char **nextcmdp, int skip) } } if (skip) { - --emsg_skip; + emsg_skip--; } return fi; @@ -2009,7 +1955,7 @@ void free_for_info(void *fi_void) void set_context_for_expression(expand_T *xp, char *arg, cmdidx_T cmdidx) FUNC_ATTR_NONNULL_ALL { - int got_eq = FALSE; + bool got_eq = false; int c; char *p; @@ -2035,7 +1981,7 @@ void set_context_for_expression(expand_T *xp, char *arg, cmdidx_T cmdidx) if (c == '&') { c = (uint8_t)xp->xp_pattern[1]; if (c == '&') { - ++xp->xp_pattern; + xp->xp_pattern++; xp->xp_context = cmdidx != CMD_let || got_eq ? EXPAND_EXPRESSION : EXPAND_NOTHING; } else if (c != ' ') { @@ -2048,7 +1994,7 @@ void set_context_for_expression(expand_T *xp, char *arg, cmdidx_T cmdidx) // environment variable xp->xp_context = EXPAND_ENV_VARS; } else if (c == '=') { - got_eq = TRUE; + got_eq = true; xp->xp_context = EXPAND_EXPRESSION; } else if (c == '#' && xp->xp_context == EXPAND_EXPRESSION) { @@ -2073,7 +2019,7 @@ void set_context_for_expression(expand_T *xp, char *arg, cmdidx_T cmdidx) xp->xp_context = EXPAND_NOTHING; } else if (c == '|') { if (xp->xp_pattern[1] == '|') { - ++xp->xp_pattern; + xp->xp_pattern++; xp->xp_context = EXPAND_EXPRESSION; } else { xp->xp_context = EXPAND_COMMANDS; @@ -2123,11 +2069,9 @@ void del_menutrans_vars(void) hash_unlock(&globvarht); } -/* - * Local string buffer for the next two functions to store a variable name - * with its prefix. Allocated in cat_prefix_varname(), freed later in - * get_user_var_name(). - */ +/// Local string buffer for the next two functions to store a variable name +/// with its prefix. Allocated in cat_prefix_varname(), freed later in +/// get_user_var_name(). static char *varnamebuf = NULL; static size_t varnamebuflen = 0; @@ -2171,10 +2115,10 @@ char *get_user_var_name(expand_T *xp, int idx) if (gdone++ == 0) { hi = globvarht.ht_array; } else { - ++hi; + hi++; } while (HASHITEM_EMPTY(hi)) { - ++hi; + hi++; } if (STRNCMP("g:", xp->xp_pattern, 2) == 0) { return cat_prefix_varname('g', (char *)hi->hi_key); @@ -2188,10 +2132,10 @@ char *get_user_var_name(expand_T *xp, int idx) if (bdone++ == 0) { hi = ht->ht_array; } else { - ++hi; + hi++; } while (HASHITEM_EMPTY(hi)) { - ++hi; + hi++; } return cat_prefix_varname('b', (char *)hi->hi_key); } @@ -2202,10 +2146,10 @@ char *get_user_var_name(expand_T *xp, int idx) if (wdone++ == 0) { hi = ht->ht_array; } else { - ++hi; + hi++; } while (HASHITEM_EMPTY(hi)) { - ++hi; + hi++; } return cat_prefix_varname('w', (char *)hi->hi_key); } @@ -2216,10 +2160,10 @@ char *get_user_var_name(expand_T *xp, int idx) if (tdone++ == 0) { hi = ht->ht_array; } else { - ++hi; + hi++; } while (HASHITEM_EMPTY(hi)) { - ++hi; + hi++; } return cat_prefix_varname('t', (char *)hi->hi_key); } @@ -2291,7 +2235,7 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ funcexe.evaluate = evaluate; funcexe.partial = partial; funcexe.basetv = basetv; - int ret = get_func_tv((char_u *)s, len, rettv, (char_u **)arg, &funcexe); + int ret = get_func_tv((char_u *)s, len, rettv, arg, &funcexe); xfree(s); @@ -2317,11 +2261,9 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ // TODO(ZyX-I): move to eval/expressions -/* - * The "evaluate" argument: When FALSE, the argument is only parsed but not - * executed. The function may return OK, but the rettv will be of type - * VAR_UNKNOWN. The function still returns FAIL for a syntax error. - */ +/// The "evaluate" argument: When FALSE, the argument is only parsed but not +/// executed. The function may return OK, but the rettv will be of type +/// VAR_UNKNOWN. The function still returns FAIL for a syntax error. /// Handle zero level expression. /// This calls eval1() and handles error message and nextcmd. @@ -2372,18 +2314,16 @@ int eval0(char *arg, typval_T *rettv, char **nextcmd, int evaluate) /// @return OK or FAIL. int eval1(char **arg, typval_T *rettv, int evaluate) { - int result; + bool result; typval_T var2; - /* - * Get the first variable. - */ + // Get the first variable. if (eval2(arg, rettv, evaluate) == FAIL) { return FAIL; } if ((*arg)[0] == '?') { - result = FALSE; + result = false; if (evaluate) { bool error = false; @@ -2396,17 +2336,13 @@ int eval1(char **arg, typval_T *rettv, int evaluate) } } - /* - * Get the second variable. - */ + // Get the second variable. *arg = skipwhite(*arg + 1); if (eval1(arg, rettv, evaluate && result) == FAIL) { // recursive! return FAIL; } - /* - * Check for the ":". - */ + // Check for the ":". if ((*arg)[0] != ':') { emsg(_("E109: Missing ':' after '?'")); if (evaluate && result) { @@ -2415,9 +2351,7 @@ int eval1(char **arg, typval_T *rettv, int evaluate) return FAIL; } - /* - * Get the third variable. - */ + // Get the third variable. *arg = skipwhite(*arg + 1); if (eval1(arg, &var2, evaluate && !result) == FAIL) { // Recursive! if (evaluate && result) { @@ -2445,22 +2379,16 @@ int eval1(char **arg, typval_T *rettv, int evaluate) static int eval2(char **arg, typval_T *rettv, int evaluate) { typval_T var2; - long result; - int first; bool error = false; - /* - * Get the first variable. - */ + // Get the first variable. if (eval3(arg, rettv, evaluate) == FAIL) { return FAIL; } - /* - * Repeat until there is no following "||". - */ - first = TRUE; - result = FALSE; + // Repeat until there is no following "||". + bool first = true; + bool result = false; while ((*arg)[0] == '|' && (*arg)[1] == '|') { if (evaluate && first) { if (tv_get_number_chk(rettv, &error) != 0) { @@ -2473,17 +2401,13 @@ static int eval2(char **arg, typval_T *rettv, int evaluate) first = false; } - /* - * Get the second variable. - */ + // Get the second variable. *arg = skipwhite(*arg + 2); if (eval3(arg, &var2, evaluate && !result) == FAIL) { return FAIL; } - /* - * Compute the result. - */ + // Compute the result. if (evaluate && !result) { if (tv_get_number_chk(&var2, &error) != 0) { result = true; @@ -2514,22 +2438,16 @@ static int eval2(char **arg, typval_T *rettv, int evaluate) static int eval3(char **arg, typval_T *rettv, int evaluate) { typval_T var2; - long result; - int first; bool error = false; - /* - * Get the first variable. - */ + // Get the first variable. if (eval4(arg, rettv, evaluate) == FAIL) { return FAIL; } - /* - * Repeat until there is no following "&&". - */ - first = TRUE; - result = TRUE; + // Repeat until there is no following "&&". + bool first = true; + bool result = true; while ((*arg)[0] == '&' && (*arg)[1] == '&') { if (evaluate && first) { if (tv_get_number_chk(rettv, &error) == 0) { @@ -2542,17 +2460,13 @@ static int eval3(char **arg, typval_T *rettv, int evaluate) first = false; } - /* - * Get the second variable. - */ + // Get the second variable. *arg = skipwhite(*arg + 2); if (eval4(arg, &var2, evaluate && result) == FAIL) { return FAIL; } - /* - * Compute the result. - */ + // Compute the result. if (evaluate && result) { if (tv_get_number_chk(&var2, &error) == 0) { result = false; @@ -2597,9 +2511,7 @@ static int eval4(char **arg, typval_T *rettv, int evaluate) int len = 2; bool ic; - /* - * Get the first variable. - */ + // Get the first variable. if (eval5(arg, rettv, evaluate) == FAIL) { return FAIL; } @@ -2648,9 +2560,7 @@ static int eval4(char **arg, typval_T *rettv, int evaluate) break; } - /* - * If there is a comparative operator, use it. - */ + // If there is a comparative operator, use it. if (type != EXPR_UNKNOWN) { // extra question mark appended: ignore case if (p[len] == '?') { @@ -2701,16 +2611,12 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) float_T f1 = 0, f2 = 0; char *p; - /* - * Get the first variable. - */ - if (eval6(arg, rettv, evaluate, FALSE) == FAIL) { + // Get the first variable. + if (eval6(arg, rettv, evaluate, false) == FAIL) { return FAIL; } - /* - * Repeat computing, until no '+', '-' or '.' is following. - */ + // Repeat computing, until no '+', '-' or '.' is following. for (;;) { op = (char_u)(**arg); if (op != '+' && op != '-' && op != '.') { @@ -2732,9 +2638,7 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) } } - /* - * Get the second variable. - */ + // Get the second variable. if (op == '.' && *(*arg + 1) == '.') { // ..string concatenation (*arg)++; } @@ -2745,9 +2649,7 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) } if (evaluate) { - /* - * Compute the result. - */ + // Compute the result. if (op == '.') { char buf1[NUMBUFLEN]; char buf2[NUMBUFLEN]; @@ -2876,16 +2778,12 @@ static int eval6(char **arg, typval_T *rettv, int evaluate, int want_string) float_T f1 = 0, f2 = 0; bool error = false; - /* - * Get the first variable. - */ + // Get the first variable. if (eval7(arg, rettv, evaluate, want_string) == FAIL) { return FAIL; } - /* - * Repeat computing, until no '*', '/' or '%' is following. - */ + // Repeat computing, until no '*', '/' or '%' is following. for (;;) { op = (char_u)(**arg); if (op != '*' && op != '/' && op != '%') { @@ -2908,9 +2806,7 @@ static int eval6(char **arg, typval_T *rettv, int evaluate, int want_string) n1 = 0; } - /* - * Get the second variable. - */ + // Get the second variable. *arg = skipwhite(*arg + 1); if (eval7(arg, &var2, evaluate, false) == FAIL) { return FAIL; @@ -2935,10 +2831,8 @@ static int eval6(char **arg, typval_T *rettv, int evaluate, int want_string) } } - /* - * Compute the result. - * When either side is a float the result is a float. - */ + // Compute the result. + // When either side is a float the result is a float. if (use_float) { if (op == '*') { f1 = f1 * f2; @@ -3051,9 +2945,9 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) get_float = true; p = skipdigits(p + 2); if (*p == 'e' || *p == 'E') { - ++p; + p++; if (*p == '-' || *p == '+') { - ++p; + p++; } if (!ascii_isdigit(*p)) { get_float = false; @@ -3147,7 +3041,7 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) // Lambda: {arg, arg -> expr} // Dictionary: {'key': val, 'key': val} case '{': - ret = get_lambda_tv((char_u **)arg, rettv, evaluate); + ret = get_lambda_tv(arg, rettv, evaluate); if (ret == NOTDONE) { ret = dict_get_tv(arg, rettv, evaluate, false); } @@ -3164,15 +3058,12 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) // Register contents: @r. case '@': - ++*arg; + (*arg)++; int regname = mb_cptr2char_adv((const char_u**) arg); if (evaluate) { rettv->v_type = VAR_STRING; rettv->vval.v_string = get_reg_contents(regname, kGRegExprSrc); } - // if (**arg != NUL) { - // ++*arg; - // } break; // nested expression: (expression). @@ -3180,7 +3071,7 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) *arg = skipwhite(*arg + 1); ret = eval1(arg, rettv, evaluate); // recursive! if (**arg == ')') { - ++*arg; + (*arg)++; } else if (ret == OK) { emsg(_("E110: Missing ')'")); tv_clear(rettv); @@ -3326,7 +3217,7 @@ static int call_func_rettv(char **const arg, typval_T *const rettv, const bool e funcexe.selfdict = selfdict; funcexe.basetv = basetv; const int ret = get_func_tv((char_u *)funcname, is_lua ? (int)(*arg - funcname) : -1, rettv, - (char_u **)arg, &funcexe); + arg, &funcexe); // Clear the funcref afterwards, so that deleting it while // evaluating the arguments is possible (see test55). @@ -3354,7 +3245,7 @@ static int eval_lambda(char **const arg, typval_T *const rettv, const bool evalu typval_T base = *rettv; rettv->v_type = VAR_UNKNOWN; - int ret = get_lambda_tv((char_u **)arg, rettv, evaluate); + int ret = get_lambda_tv(arg, rettv, evaluate); if (ret != OK) { return FAIL; } else if (**arg != '(') { @@ -3504,9 +3395,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) typval_T var1 = TV_INITIAL_VALUE; typval_T var2 = TV_INITIAL_VALUE; if (**arg == '.') { - /* - * dict.name - */ + // dict.name key = *arg + 1; for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; len++) {} if (len == 0) { @@ -3514,11 +3403,9 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) } *arg = skipwhite(key + len); } else { - /* - * something[idx] - * - * Get the (first) variable from inside the []. - */ + // something[idx] + // + // Get the (first) variable from inside the []. *arg = skipwhite(*arg + 1); if (**arg == ':') { empty1 = true; @@ -3530,9 +3417,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) return FAIL; } - /* - * Get the second variable from inside the [:]. - */ + // Get the second variable from inside the [:]. if (**arg == ':') { range = true; *arg = skipwhite(*arg + 1); @@ -3773,11 +3658,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) int get_option_tv(const char **const arg, typval_T *const rettv, const bool evaluate) FUNC_ATTR_NONNULL_ARG(1) { - long numval; - char *stringval; - getoption_T opt_type; bool working = (**arg == '+'); // has("+option") - int ret = OK; int opt_flags; // Isolate the option name and find its value. @@ -3794,10 +3675,14 @@ int get_option_tv(const char **const arg, typval_T *const rettv, const bool eval return OK; } + long numval; + char *stringval; + int ret = OK; + char c = *option_end; *option_end = NUL; - opt_type = get_option_value(*arg, &numval, - rettv == NULL ? NULL : &stringval, opt_flags); + getoption_T opt_type = get_option_value(*arg, &numval, + rettv == NULL ? NULL : &stringval, opt_flags); if (opt_type == gov_unknown) { if (rettv != NULL) { @@ -3838,9 +3723,7 @@ static int get_string_tv(char **arg, typval_T *rettv, int evaluate) char *p; unsigned int extra = 0; - /* - * Find the end of the string, skipping backslashed characters. - */ + // Find the end of the string, skipping backslashed characters. for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) { if (*p == '\\' && p[1] != NUL) { p++; @@ -3864,10 +3747,8 @@ static int get_string_tv(char **arg, typval_T *rettv, int evaluate) return OK; } - /* - * Copy the string into allocated memory, handling backslashed - * characters. - */ + // Copy the string into allocated memory, handling backslashed + // characters. const int len = (int)(p - *arg + extra); char *name = xmalloc((size_t)len); rettv->v_type = VAR_STRING; @@ -3906,7 +3787,7 @@ static int get_string_tv(char **arg, typval_T *rettv, int evaluate) } nr = 0; while (--n >= 0 && ascii_isxdigit(p[1])) { - ++p; + p++; nr = (nr << 4) + hex2nr(*p); } p++; @@ -3936,7 +3817,7 @@ static int get_string_tv(char **arg, typval_T *rettv, int evaluate) *name = (char)((*name << 3) + *p++ - '0'); } } - ++name; + name++; break; // Special key, e.g.: "\<C-W>" @@ -3958,11 +3839,11 @@ static int get_string_tv(char **arg, typval_T *rettv, int evaluate) FALLTHROUGH; default: - mb_copy_char((const char_u **)&p, (char_u **)&name); + mb_copy_char((const char **)&p, &name); break; } } else { - mb_copy_char((const char_u **)&p, (char_u **)&name); + mb_copy_char((const char **)&p, &name); } } *name = NUL; @@ -3980,19 +3861,16 @@ static int get_string_tv(char **arg, typval_T *rettv, int evaluate) static int get_lit_string_tv(char **arg, typval_T *rettv, int evaluate) { char *p; - char *str; int reduce = 0; - /* - * Find the end of the string, skipping ''. - */ + // Find the end of the string, skipping ''. for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p)) { if (*p == '\'') { if (p[1] != '\'') { break; } - ++reduce; - ++p; + reduce++; + p++; } } @@ -4007,10 +3885,8 @@ static int get_lit_string_tv(char **arg, typval_T *rettv, int evaluate) return OK; } - /* - * Copy the string into allocated memory, handling '' to ' reduction. - */ - str = xmalloc((size_t)((p - *arg) - reduce)); + // Copy the string into allocated memory, handling '' to ' reduction. + char *str = xmalloc((size_t)((p - *arg) - reduce)); rettv->v_type = VAR_STRING; rettv->vval.v_string = str; @@ -4019,9 +3895,9 @@ static int get_lit_string_tv(char **arg, typval_T *rettv, int evaluate) if (p[1] != '\'') { break; } - ++p; + p++; } - mb_copy_char((const char_u **)&p, (char_u **)&str); + mb_copy_char((const char **)&p, &str); } *str = NUL; *arg = p + 1; @@ -4120,16 +3996,14 @@ failret: /// @param ic ignore case bool func_equal(typval_T *tv1, typval_T *tv2, bool ic) { - char_u *s1, *s2; - dict_T *d1, *d2; - int a1, a2; - // empty and NULL function name considered the same - s1 = (char_u *)(tv1->v_type == VAR_FUNC ? tv1->vval.v_string : partial_name(tv1->vval.v_partial)); + char_u *s1 = + (char_u *)(tv1->v_type == VAR_FUNC ? tv1->vval.v_string : partial_name(tv1->vval.v_partial)); if (s1 != NULL && *s1 == NUL) { s1 = NULL; } - s2 = (char_u *)(tv2->v_type == VAR_FUNC ? tv2->vval.v_string : partial_name(tv2->vval.v_partial)); + char_u *s2 = + (char_u *)(tv2->v_type == VAR_FUNC ? tv2->vval.v_string : partial_name(tv2->vval.v_partial)); if (s2 != NULL && *s2 == NUL) { s2 = NULL; } @@ -4142,8 +4016,8 @@ bool func_equal(typval_T *tv1, typval_T *tv2, bool ic) } // empty dict and NULL dict is different - d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict; - d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict; + dict_T *d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict; + dict_T *d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict; if (d1 == NULL || d2 == NULL) { if (d1 != d2) { return false; @@ -4153,8 +4027,8 @@ bool func_equal(typval_T *tv1, typval_T *tv2, bool ic) } // empty list and no list considered the same - a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc; - a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc; + int a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc; + int a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc; if (a1 != a2) { return false; } @@ -4183,25 +4057,23 @@ int get_copyID(void) return current_copyID; } -/* - * Garbage collection for lists and dictionaries. - * - * We use reference counts to be able to free most items right away when they - * are no longer used. But for composite items it's possible that it becomes - * unused while the reference count is > 0: When there is a recursive - * reference. Example: - * :let l = [1, 2, 3] - * :let d = {9: l} - * :let l[1] = d - * - * Since this is quite unusual we handle this with garbage collection: every - * once in a while find out which lists and dicts are not referenced from any - * variable. - * - * Here is a good reference text about garbage collection (refers to Python - * but it applies to all reference-counting mechanisms): - * http://python.ca/nas/python/gc/ - */ +/// Garbage collection for lists and dictionaries. +/// +/// We use reference counts to be able to free most items right away when they +/// are no longer used. But for composite items it's possible that it becomes +/// unused while the reference count is > 0: When there is a recursive +/// reference. Example: +/// :let l = [1, 2, 3] +/// :let d = {9: l} +/// :let l[1] = d +/// +/// Since this is quite unusual we handle this with garbage collection: every +/// once in a while find out whic |