diff options
author | Josh Rahm <rahm@google.com> | 2022-08-19 12:26:08 -0600 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-08-19 13:06:41 -0600 |
commit | a7237662f96933efe29eed8212464571e3778cd0 (patch) | |
tree | 27930202726b4251437c8cfa53069f65b4db90dc /src/nvim/eval | |
parent | 02292344929069ea63c0bb872cc22d552d86b67f (diff) | |
parent | b2f979b30beac67906b2dd717fcb6a34f46f5e54 (diff) | |
download | rneovim-tmp.tar.gz rneovim-tmp.tar.bz2 rneovim-tmp.zip |
Merge branch 'master' of https://github.com/neovim/neovim into rahmtmp
Diffstat (limited to 'src/nvim/eval')
-rw-r--r-- | src/nvim/eval/encode.c | 6 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 1042 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/typval.h | 5 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 352 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.h | 9 | ||||
-rw-r--r-- | src/nvim/eval/vars.c | 3 |
7 files changed, 400 insertions, 1021 deletions
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 090939666d..bb514fba47 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -30,12 +30,12 @@ #include "nvim/vim.h" // For _() const char *const encode_bool_var_names[] = { - [kBoolVarTrue] = "true", - [kBoolVarFalse] = "false", + [kBoolVarTrue] = "v:true", + [kBoolVarFalse] = "v:false", }; const char *const encode_special_var_names[] = { - [kSpecialVarNull] = "null", + [kSpecialVarNull] = "v:null", }; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index f24285063e..3b9dc92137 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -7,12 +7,14 @@ #include "nvim/api/private/converter.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" +#include "nvim/arglist.h" #include "nvim/ascii.h" #include "nvim/assert.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/channel.h" #include "nvim/charset.h" +#include "nvim/cmdhist.h" #include "nvim/context.h" #include "nvim/cursor.h" #include "nvim/diff.h" @@ -27,10 +29,12 @@ #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" #include "nvim/ex_docmd.h" +#include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/highlight_group.h" #include "nvim/if_cscope.h" @@ -45,6 +49,7 @@ #include "nvim/match.h" #include "nvim/math.h" #include "nvim/memline.h" +#include "nvim/menu.h" #include "nvim/mouse.h" #include "nvim/move.h" #include "nvim/msgpack_rpc/channel.h" @@ -52,18 +57,20 @@ #include "nvim/ops.h" #include "nvim/option.h" #include "nvim/os/dl.h" -#include "nvim/os/input.h" #include "nvim/os/shell.h" #include "nvim/path.h" #include "nvim/plines.h" -#include "nvim/popupmnu.h" +#include "nvim/popupmenu.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/sha256.h" #include "nvim/sign.h" #include "nvim/spell.h" +#include "nvim/spellsuggest.h" #include "nvim/state.h" #include "nvim/syntax.h" #include "nvim/tag.h" @@ -117,13 +124,12 @@ static va_list dummy_ap; char *get_function_name(expand_T *xp, int idx) { static int intidx = -1; - char_u *name; if (idx == 0) { intidx = -1; } if (intidx < 0) { - name = (char_u *)get_user_func_name(xp, idx); + char_u *name = (char_u *)get_user_func_name(xp, idx); if (name != NULL) { if (*name != NUL && *name != '<' && STRNCMP("g:", xp->xp_pattern, 2) == 0) { @@ -154,13 +160,12 @@ char *get_function_name(expand_T *xp, int idx) char *get_expr_name(expand_T *xp, int idx) { static int intidx = -1; - char_u *name; if (idx == 0) { intidx = -1; } if (intidx < 0) { - name = (char_u *)get_function_name(xp, idx); + char_u *name = (char_u *)get_function_name(xp, idx); if (name != NULL) { return (char *)name; } @@ -294,10 +299,9 @@ static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type == VAR_FLOAT) { float_op_wrapper(argvars, rettv, (FunPtr)&fabs); } else { - varnumber_T n; bool error = false; - n = tv_get_number_chk(&argvars[0], &error); + varnumber_T n = tv_get_number_chk(&argvars[0], &error); if (error) { rettv->vval.v_number = -1; } else if (n > 0) { @@ -371,77 +375,6 @@ static void f_appendbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -static void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - if (argvars[0].v_type == VAR_UNKNOWN) { - // use the current window - rettv->vval.v_number = ARGCOUNT; - } else if (argvars[0].v_type == VAR_NUMBER - && tv_get_number(&argvars[0]) == -1) { - // use the global argument list - rettv->vval.v_number = GARGCOUNT; - } else { - // use the argument list of the specified window - win_T *wp = find_win_by_nr_or_id(&argvars[0]); - if (wp != NULL) { - rettv->vval.v_number = WARGCOUNT(wp); - } else { - rettv->vval.v_number = -1; - } - } -} - -/// "argidx()" function -static void f_argidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = curwin->w_arg_idx; -} - -/// "arglistid" function -static void f_arglistid(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = -1; - win_T *wp = find_tabwin(&argvars[0], &argvars[1]); - if (wp != NULL) { - rettv->vval.v_number = wp->w_alist->id; - } -} - -/// "argv(nr)" function -static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - aentry_T *arglist = NULL; - int argcount = -1; - - if (argvars[0].v_type != VAR_UNKNOWN) { - if (argvars[1].v_type == VAR_UNKNOWN) { - arglist = ARGLIST; - argcount = ARGCOUNT; - } else if (argvars[1].v_type == VAR_NUMBER - && tv_get_number(&argvars[1]) == -1) { - arglist = GARGLIST; - argcount = GARGCOUNT; - } else { - win_T *wp = find_win_by_nr_or_id(&argvars[1]); - if (wp != NULL) { - // Use the argument list of the specified window - arglist = WARGLIST(wp); - argcount = WARGCOUNT(wp); - } - } - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - int idx = (int)tv_get_number_chk(&argvars[0], NULL); - if (arglist != NULL && idx >= 0 && idx < argcount) { - rettv->vval.v_string = xstrdup((const char *)alist_name(&arglist[idx])); - } else if (idx == -1) { - get_arglist_as_rettv(arglist, argcount, rettv); - } - } else { - get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv); - } -} - /// "atan2()" function static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -479,8 +412,8 @@ static buf_T *find_buffer(typval_T *avar) } else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) { buf = buflist_findname_exp(avar->vval.v_string); if (buf == NULL) { - /* No full path name match, try a match with a URL or a "nofile" - * buffer, these don't use the full path. */ + // No full path name match, try a match with a URL or a "nofile" + // buffer, these don't use the full path. FOR_ALL_BUFFERS(bp) { if (bp->b_fname != NULL && (path_with_url(bp->b_fname) || bt_nofilename(bp)) @@ -632,17 +565,15 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Get buffer by number or pattern. buf_T *tv_get_buf(typval_T *tv, int curtab_only) { - char_u *name = (char_u *)tv->vval.v_string; - int save_magic; - char *save_cpo; - buf_T *buf; - if (tv->v_type == VAR_NUMBER) { return buflist_findnr((int)tv->vval.v_number); } if (tv->v_type != VAR_STRING) { return NULL; } + + char_u *name = (char_u *)tv->vval.v_string; + if (name == NULL || *name == NUL) { return curbuf; } @@ -651,13 +582,13 @@ buf_T *tv_get_buf(typval_T *tv, int curtab_only) } // Ignore 'magic' and 'cpoptions' here to make scripts portable - save_magic = p_magic; - p_magic = TRUE; - save_cpo = p_cpo; + int save_magic = p_magic; + p_magic = true; + char *save_cpo = p_cpo; p_cpo = ""; - buf = buflist_findnr(buflist_findpat((char *)name, (char *)name + STRLEN(name), - true, false, curtab_only)); + buf_T *buf = buflist_findnr(buflist_findpat((char *)name, (char *)name + STRLEN(name), + true, false, curtab_only)); p_magic = save_magic; p_cpo = save_cpo; @@ -686,10 +617,8 @@ buf_T *tv_get_buf_from_arg(typval_T *const tv) FUNC_ATTR_NONNULL_ALL /// valid. buf_T *get_buf_arg(typval_T *arg) { - buf_T *buf; - emsg_off++; - buf = tv_get_buf(arg, false); + buf_T *buf = tv_get_buf(arg, false); emsg_off--; if (buf == NULL) { semsg(_("E158: Invalid buffer name: %s"), tv_get_string(arg)); @@ -735,13 +664,13 @@ static void byteidx(typval_T *argvars, typval_T *rettv, int comp) /// "byteidx()" function static void f_byteidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - byteidx(argvars, rettv, FALSE); + byteidx(argvars, rettv, false); } /// "byteidxcomp()" function static void f_byteidxcomp(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - byteidx(argvars, rettv, TRUE); + byteidx(argvars, rettv, true); } /// "call(func, arglist [, dict])" function @@ -758,7 +687,6 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool owned = false; char_u *func; partial_T *partial = NULL; - dict_T *selfdict = NULL; if (argvars[0].v_type == VAR_FUNC) { func = (char_u *)argvars[0].vval.v_string; } else if (argvars[0].v_type == VAR_PARTIAL) { @@ -776,6 +704,7 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; // type error or empty name } + dict_T *selfdict = NULL; if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_DICT) { emsg(_(e_dictreq)); @@ -898,10 +827,9 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void get_col(typval_T *argvars, typval_T *rettv, bool charcol) { colnr_T col = 0; - pos_T *fp; int fnum = curbuf->b_fnum; - fp = var2fpos(&argvars[0], false, &fnum, charcol); + pos_T *fp = var2fpos(&argvars[0], false, &fnum, charcol); if (fp != NULL && fnum == curbuf->b_fnum) { if (fp->col == MAXCOL) { // '> can be MAXCOL, get the length of the line then @@ -984,9 +912,6 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "chdir(dir)" function static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u *cwd; - CdScope scope = kCdScopeGlobal; - rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -997,7 +922,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // Return the current directory - cwd = xmalloc(MAXPATHL); + char_u *cwd = xmalloc(MAXPATHL); if (os_dirname(cwd, MAXPATHL) != FAIL) { #ifdef BACKSLASH_IN_FILENAME slash_adjust(cwd); @@ -1006,6 +931,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } xfree(cwd); + CdScope scope = kCdScopeGlobal; if (curwin->w_localdir != NULL) { scope = kCdScopeWindow; } else if (curtab->tp_localdir != NULL) { @@ -1021,11 +947,8 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "cindent(lnum)" function static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - pos_T pos; - linenr_T lnum; - - pos = curwin->w_cursor; - lnum = tv_get_lnum(argvars); + pos_T pos = curwin->w_cursor; + linenr_T lnum = tv_get_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { curwin->w_cursor.lnum = lnum; rettv->vval.v_number = get_c_indent(); @@ -1060,14 +983,12 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char buf[NUMBUFLEN]; char buf2[NUMBUFLEN]; - const char *message; const char *buttons = NULL; int def = 1; int type = VIM_GENERIC; - const char *typestr; bool error = false; - message = tv_get_string_chk(&argvars[0]); + const char *message = tv_get_string_chk(&argvars[0]); if (message == NULL) { error = true; } @@ -1079,7 +1000,7 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[2].v_type != VAR_UNKNOWN) { def = (int)tv_get_number_chk(&argvars[2], &error); if (argvars[3].v_type != VAR_UNKNOWN) { - typestr = tv_get_string_buf_chk(&argvars[3], buf2); + const char *typestr = tv_get_string_buf_chk(&argvars[3], buf2); if (typestr == NULL) { error = true; } else { @@ -1152,15 +1073,13 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } else if (argvars[0].v_type == VAR_LIST) { - listitem_T *li; - list_T *l; - long idx; + list_T *l = argvars[0].vval.v_list; - if ((l = argvars[0].vval.v_list) != NULL) { - li = tv_list_first(l); + if (l != NULL) { + listitem_T *li = tv_list_first(l); if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[3].v_type != VAR_UNKNOWN) { - idx = tv_get_number_chk(&argvars[3], &error); + long idx = tv_get_number_chk(&argvars[3], &error); if (!error) { li = tv_list_find(l, (int)idx); if (li == NULL) { @@ -1180,19 +1099,17 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } else if (argvars[0].v_type == VAR_DICT) { - int todo; - dict_T *d; - hashitem_T *hi; + dict_T *d = argvars[0].vval.v_dict; - if ((d = argvars[0].vval.v_dict) != NULL) { + if (d != NULL) { if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[3].v_type != VAR_UNKNOWN) { emsg(_(e_invarg)); } } - todo = error ? 0 : (int)d->dv_hashtab.ht_used; - for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) { + int todo = error ? 0 : (int)d->dv_hashtab.ht_used; + for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) { if (!HASHITEM_EMPTY(hi)) { todo--; if (tv_equal(&TV_DICT_HI2DI(hi)->di_tv, &argvars[1], ic, false)) { @@ -1414,10 +1331,8 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "debugbreak()" function static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int pid; - rettv->vval.v_number = FAIL; - pid = (int)tv_get_number(&argvars[0]); + int pid = (int)tv_get_number(&argvars[0]); if (pid == 0) { emsg(_(e_invarg)); } else { @@ -1564,10 +1479,6 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "deletebufline()" function static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - linenr_T last; - buf_T *curbuf_save = NULL; - win_T *curwin_save = NULL; - buf_T *const buf = tv_get_buf(&argvars[0], false); if (buf == NULL) { rettv->vval.v_number = 1; // FAIL @@ -1576,6 +1487,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) const bool is_curbuf = buf == curbuf; const bool save_VIsual_active = VIsual_active; + linenr_T last; const linenr_T first = tv_get_lnum_buf(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { last = tv_get_lnum_buf(&argvars[2], buf); @@ -1589,6 +1501,8 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + buf_T *curbuf_save = NULL; + win_T *curwin_save = NULL; if (!is_curbuf) { VIsual_active = false; curbuf_save = curbuf; @@ -1660,8 +1574,6 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) static int change_start = 0; static int change_end = 0; static hlf_T hlID = (hlf_T)0; - int filler_lines; - int col; if (lnum < 0) { // ignore type error in {lnum} arg lnum = 0; @@ -1670,7 +1582,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) || changedtick != buf_get_changedtick(curbuf) || fnum != curbuf->b_fnum) { // New line, buffer, change: need to get the values. - filler_lines = diff_check(curwin, lnum); + int filler_lines = diff_check(curwin, lnum); if (filler_lines < 0) { if (filler_lines == -1) { change_start = MAXCOL; @@ -1692,7 +1604,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (hlID == HLF_CHD || hlID == HLF_TXD) { - col = (int)tv_get_number(&argvars[1]) - 1; // Ignore type error in {col}. + int col = (int)tv_get_number(&argvars[1]) - 1; // Ignore type error in {col}. if (col >= change_start && col <= change_end) { hlID = HLF_TXD; // Changed text. } else { @@ -2042,12 +1954,9 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "expand()" function static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - size_t len; char *errormsg; int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; - expand_T xpc; bool error = false; - char_u *result; #ifdef BACKSLASH_IN_FILENAME char_u *p_csl_save = p_csl; @@ -2066,7 +1975,8 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *s = tv_get_string(&argvars[0]); if (*s == '%' || *s == '#' || *s == '<') { emsg_off++; - result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL); + size_t len; + char_u *result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL); emsg_off--; if (rettv->v_type == VAR_LIST) { tv_list_alloc_ret(rettv, (result != NULL)); @@ -2085,6 +1995,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) options |= WILD_KEEP_ALL; } if (!error) { + expand_T xpc; ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; if (p_wic) { @@ -2151,8 +2062,6 @@ static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "flatten(list[, {maxdepth}])" function static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - list_T *list; - long maxdepth; bool error = false; if (argvars[0].v_type != VAR_LIST) { @@ -2160,6 +2069,7 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + long maxdepth; if (argvars[1].v_type == VAR_UNKNOWN) { maxdepth = 999999; } else { @@ -2173,7 +2083,7 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - list = argvars[0].vval.v_list; + list_T *list = argvars[0].vval.v_list; if (list != NULL && !var_check_lock(tv_list_locked(list), N_("flatten() argument"), @@ -2190,7 +2100,6 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *const arg_errmsg = N_("extend() argument"); if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) { - long before; bool error = false; list_T *const l1 = argvars[0].vval.v_list; @@ -2198,7 +2107,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (!var_check_lock(tv_list_locked(l1), arg_errmsg, TV_TRANSLATE)) { listitem_T *item; if (argvars[2].v_type != VAR_UNKNOWN) { - before = (long)tv_get_number_chk(&argvars[2], &error); + long before = (long)tv_get_number_chk(&argvars[2], &error); if (error) { return; // Type error; errmsg already given. } @@ -2360,7 +2269,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) /// "filter()" function static void f_filter(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - filter_map(argvars, rettv, FALSE); + filter_map(argvars, rettv, false); } /// "finddir({fname}[, {path}[, {count}]])" function @@ -2440,130 +2349,6 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr) xfree(fbuf); } -/// "foldclosed()" function -static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end) -{ - const linenr_T lnum = tv_get_lnum(argvars); - if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { - linenr_T first; - linenr_T last; - if (hasFoldingWin(curwin, lnum, &first, &last, false, NULL)) { - if (end) { - rettv->vval.v_number = (varnumber_T)last; - } else { - rettv->vval.v_number = (varnumber_T)first; - } - return; - } - } - rettv->vval.v_number = -1; -} - -/// "foldclosed()" function -static void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - foldclosed_both(argvars, rettv, FALSE); -} - -/// "foldclosedend()" function -static void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - foldclosed_both(argvars, rettv, TRUE); -} - -/// "foldlevel()" function -static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - const linenr_T lnum = tv_get_lnum(argvars); - if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { - rettv->vval.v_number = foldLevel(lnum); - } -} - -/// "foldtext()" function -static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - linenr_T foldstart; - linenr_T foldend; - char_u *dashes; - linenr_T lnum; - char_u *s; - char_u *r; - int len; - char *txt; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - - foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART); - foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND); - dashes = (char_u *)get_vim_var_str(VV_FOLDDASHES); - if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) { - // Find first non-empty line in the fold. - for (lnum = foldstart; lnum < foldend; lnum++) { - if (!linewhite(lnum)) { - break; - } - } - - // Find interesting text in this line. - s = (char_u *)skipwhite((char *)ml_get(lnum)); - // skip C comment-start - if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) { - s = (char_u *)skipwhite((char *)s + 2); - if (*skipwhite((char *)s) == NUL && lnum + 1 < foldend) { - s = (char_u *)skipwhite((char *)ml_get(lnum + 1)); - if (*s == '*') { - s = (char_u *)skipwhite((char *)s + 1); - } - } - } - unsigned long count = (unsigned long)foldend - (unsigned long)foldstart + 1; - txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count); - r = xmalloc(STRLEN(txt) - + STRLEN(dashes) // for %s - + 20 // for %3ld - + STRLEN(s)); // concatenated - sprintf((char *)r, txt, dashes, count); - len = (int)STRLEN(r); - STRCAT(r, s); - // remove 'foldmarker' and 'commentstring' - foldtext_cleanup(r + len); - rettv->vval.v_string = (char *)r; - } -} - -/// "foldtextresult(lnum)" function -static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - char_u *text; - char_u buf[FOLD_TEXT_LEN]; - static bool entered = false; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - if (entered) { - return; // reject recursive use - } - entered = true; - linenr_T lnum = tv_get_lnum(argvars); - // Treat illegal types and illegal string values for {lnum} the same. - if (lnum < 0) { - lnum = 0; - } - - foldinfo_T info = fold_info(curwin, lnum); - if (info.fi_lines > 0) { - text = get_foldtext(curwin, lnum, lnum + (linenr_T)info.fi_lines - 1, info, buf); - if (text == buf) { - text = vim_strsave(text); - } - rettv->vval.v_string = (char *)text; - } - - entered = false; -} - /// "foreground()" function static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr) {} @@ -2593,10 +2378,6 @@ static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "get()" function static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - listitem_T *li; - list_T *l; - dictitem_T *di; - dict_T *d; typval_T *tv = NULL; bool what_is_dict = false; @@ -2617,17 +2398,19 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } else if (argvars[0].v_type == VAR_LIST) { - if ((l = argvars[0].vval.v_list) != NULL) { + list_T *l = argvars[0].vval.v_list; + if (l != NULL) { bool error = false; - li = tv_list_find(l, (int)tv_get_number_chk(&argvars[1], &error)); + listitem_T *li = tv_list_find(l, (int)tv_get_number_chk(&argvars[1], &error)); if (!error && li != NULL) { tv = TV_LIST_ITEM_TV(li); } } } else if (argvars[0].v_type == VAR_DICT) { - if ((d = argvars[0].vval.v_dict) != NULL) { - di = tv_dict_find(d, tv_get_string(&argvars[1]), -1); + dict_T *d = argvars[0].vval.v_dict; + if (d != NULL) { + dictitem_T *di = tv_dict_find(d, tv_get_string(&argvars[1]), -1); if (di != NULL) { tv = &di->di_tv; } @@ -2639,7 +2422,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type == VAR_PARTIAL) { pt = argvars[0].vval.v_partial; } else { - memset(&fref_pt, 0, sizeof(fref_pt)); + CLEAR_FIELD(fref_pt); fref_pt.pt_name = (char_u *)argvars[0].vval.v_string; pt = &fref_pt; } @@ -2851,147 +2634,6 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/// "getchar()" and "getcharstr()" functions -static void getchar_common(typval_T *argvars, typval_T *rettv) - FUNC_ATTR_NONNULL_ALL -{ - varnumber_T n; - bool error = false; - - no_mapping++; - allow_keys++; - for (;;) { - // Position the cursor. Needed after a message that ends in a space, - // or if event processing caused a redraw. - ui_cursor_goto(msg_row, msg_col); - - if (argvars[0].v_type == VAR_UNKNOWN) { - // getchar(): blocking wait. - // TODO(bfredl): deduplicate shared logic with state_enter ? - if (!char_avail()) { - (void)os_inchar(NULL, 0, -1, 0, main_loop.events); - if (!multiqueue_empty(main_loop.events)) { - state_handle_k_event(); - continue; - } - } - n = safe_vgetc(); - } else if (tv_get_number_chk(&argvars[0], &error) == 1) { - // getchar(1): only check if char avail - n = vpeekc_any(); - } else if (error || vpeekc_any() == NUL) { - // illegal argument or getchar(0) and no char avail: return zero - n = 0; - } else { - // getchar(0) and char avail() != NUL: get a character. - // Note that vpeekc_any() returns K_SPECIAL for K_IGNORE. - n = safe_vgetc(); - } - - if (n == K_IGNORE - || n == K_MOUSEMOVE - || n == K_VER_SCROLLBAR - || n == K_HOR_SCROLLBAR) { - continue; - } - break; - } - no_mapping--; - allow_keys--; - - if (!ui_has_messages()) { - // redraw the screen after getchar() - update_screen(CLEAR); - } - - set_vim_var_nr(VV_MOUSE_WIN, 0); - set_vim_var_nr(VV_MOUSE_WINID, 0); - set_vim_var_nr(VV_MOUSE_LNUM, 0); - set_vim_var_nr(VV_MOUSE_COL, 0); - - rettv->vval.v_number = n; - if (n != 0 && (IS_SPECIAL(n) || mod_mask != 0)) { - char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1 - int i = 0; - - // Turn a special key into three bytes, plus modifier. - if (mod_mask != 0) { - temp[i++] = K_SPECIAL; - temp[i++] = KS_MODIFIER; - temp[i++] = (char_u)mod_mask; - } - if (IS_SPECIAL(n)) { - temp[i++] = K_SPECIAL; - temp[i++] = (char_u)K_SECOND(n); - temp[i++] = K_THIRD(n); - } else { - i += utf_char2bytes((int)n, (char *)temp + i); - } - assert(i < 10); - temp[i++] = NUL; - rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)vim_strsave(temp); - - if (is_mouse_key((int)n)) { - int row = mouse_row; - int col = mouse_col; - int grid = mouse_grid; - linenr_T lnum; - win_T *wp; - int winnr = 1; - - if (row >= 0 && col >= 0) { - // Find the window at the mouse coordinates and compute the - // text position. - win_T *const win = mouse_find_win(&grid, &row, &col); - if (win == NULL) { - return; - } - (void)mouse_comp_pos(win, &row, &col, &lnum); - for (wp = firstwin; wp != win; wp = wp->w_next) { - ++winnr; - } - set_vim_var_nr(VV_MOUSE_WIN, winnr); - set_vim_var_nr(VV_MOUSE_WINID, wp->handle); - set_vim_var_nr(VV_MOUSE_LNUM, lnum); - set_vim_var_nr(VV_MOUSE_COL, col + 1); - } - } - } -} - -/// "getchar()" function -static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - getchar_common(argvars, rettv); -} - -/// "getcharstr()" function -static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - getchar_common(argvars, rettv); - - if (rettv->v_type == VAR_NUMBER) { - char temp[7]; // mbyte-char: 6, NUL: 1 - const varnumber_T n = rettv->vval.v_number; - int i = 0; - - if (n != 0) { - i += utf_char2bytes((int)n, (char *)temp); - } - assert(i < 7); - temp[i++] = NUL; - rettv->v_type = VAR_STRING; - rettv->vval.v_string = xstrdup(temp); - } -} - -/// "getcharmod()" function -static void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = mod_mask; -} - static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos, bool charcol) { pos_T *fp = NULL; @@ -3203,15 +2845,15 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Numbers of the scope objects (window, tab) we want the working directory // of. A `-1` means to skip this scope, a `0` means the current object. int scope_number[] = { - [kCdScopeWindow] = 0, // Number of window to look at. + [kCdScopeWindow] = 0, // Number of window to look at. [kCdScopeTabpage] = 0, // Number of tab to look at. }; char *cwd = NULL; // Current working directory to print char *from = NULL; // The original string to copy - tabpage_T *tp = curtab; // The tabpage to look at. - win_T *win = curwin; // The window to look at. + tabpage_T *tp = curtab; // The tabpage to look at. + win_T *win = curwin; // The window to look at. rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -3455,13 +3097,6 @@ static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr) get_buffer_lines(curbuf, lnum, end, retlist, rettv); } -/// "getloclist()" function -static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - win_T *wp = find_win_by_nr_or_id(&argvars[0]); - get_qf_loc_list(false, wp, &argvars[1], rettv); -} - /// "getmarklist()" function static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -3483,8 +3118,6 @@ static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "getmousepos()" function static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - dict_T *d; - win_T *wp; int row = mouse_row; int col = mouse_col; int grid = mouse_grid; @@ -3495,12 +3128,12 @@ static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr) varnumber_T column = 0; tv_dict_alloc_ret(rettv); - d = rettv->vval.v_dict; + dict_T *d = rettv->vval.v_dict; tv_dict_add_nr(d, S_LEN("screenrow"), (varnumber_T)mouse_row + 1); tv_dict_add_nr(d, S_LEN("screencol"), (varnumber_T)mouse_col + 1); - wp = mouse_find_win(&grid, &row, &col); + win_T *wp = mouse_find_win(&grid, &row, &col); if (wp != NULL) { int height = wp->w_height + wp->w_hsep_height + wp->w_status_height; // The height is adjusted by 1 when there is a bottom border. This is not @@ -3546,12 +3179,6 @@ static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) getpos_both(argvars, rettv, false, false); } -/// "getqflist()" functions -static void f_getqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - get_qf_loc_list(true, NULL, &argvars[0], rettv); -} - /// Common between getreg(), getreginfo() and getregtype(): get the register /// name from the first argument. /// Returns zero on error. @@ -3788,7 +3415,6 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Move the window wp into a new split of targetwin in a given direction static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags) { - int dir; int height = wp->w_height; win_T *oldwin = curwin; @@ -3802,6 +3428,7 @@ static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags } // Remove the old window and frame from the tree of frames + int dir; (void)winframe_remove(wp, &dir, NULL); win_remove(wp, NULL); last_status(false); // may need to remove last status line @@ -3826,12 +3453,8 @@ static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags /// "win_splitmove()" function static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - win_T *wp; - win_T *targetwin; - int flags = 0, size = 0; - - wp = find_win_by_nr_or_id(&argvars[0]); - targetwin = find_win_by_nr_or_id(&argvars[1]); + win_T *wp = find_win_by_nr_or_id(&argvars[0]); + win_T *targetwin = find_win_by_nr_or_id(&argvars[1]); if (wp == NULL || targetwin == NULL || wp == targetwin || !win_valid(wp) || !win_valid(targetwin) @@ -3841,6 +3464,8 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + int flags = 0, size = 0; + if (argvars[2].v_type != VAR_UNKNOWN) { dict_T *d; dictitem_T *di; @@ -3890,8 +3515,8 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) expand_T xpc; bool error = false; - /* When the optional second argument is non-zero, don't remove matches - * for 'wildignore' and don't put matches for 'suffixes' at the end. */ + // When the optional second argument is non-zero, don't remove matches + // for 'wildignore' and don't put matches for 'suffixes' at the end. rettv->v_type = VAR_STRING; if (argvars[1].v_type != VAR_UNKNOWN) { if (tv_get_number_chk(&argvars[1], &error)) { @@ -3964,7 +3589,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (file != NULL && !error) { garray_T ga; ga_init(&ga, (int)sizeof(char_u *), 10); - globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags); + globpath((char *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags); if (rettv->v_type == VAR_STRING) { rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n"); @@ -4306,87 +3931,6 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/// "histadd()" function -static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - HistoryType histype; - - rettv->vval.v_number = false; - if (check_secure()) { - return; - } - const char *str = tv_get_string_chk(&argvars[0]); // NULL on type error - histype = str != NULL ? get_histtype(str, strlen(str), false) : HIST_INVALID; - if (histype != HIST_INVALID) { - char buf[NUMBUFLEN]; - str = tv_get_string_buf(&argvars[1], buf); - if (*str != NUL) { - init_history(); - add_to_history(histype, (char_u *)str, false, NUL); - rettv->vval.v_number = true; - return; - } - } -} - -/// "histdel()" function -static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - int n; - const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error - if (str == NULL) { - n = 0; - } else if (argvars[1].v_type == VAR_UNKNOWN) { - // only one argument: clear entire history - n = clr_history(get_histtype(str, strlen(str), false)); - } else if (argvars[1].v_type == VAR_NUMBER) { - // index given: remove that entry - n = del_history_idx(get_histtype(str, strlen(str), false), - (int)tv_get_number(&argvars[1])); - } else { - // string given: remove all matching entries - char buf[NUMBUFLEN]; - n = del_history_entry(get_histtype(str, strlen(str), false), - (char_u *)tv_get_string_buf(&argvars[1], buf)); - } - rettv->vval.v_number = n; -} - -/// "histget()" function -static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - HistoryType type; - int idx; - - const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error - if (str == NULL) { - rettv->vval.v_string = NULL; - } else { - type = get_histtype(str, strlen(str), false); - if (argvars[1].v_type == VAR_UNKNOWN) { - idx = get_history_idx(type); - } else { - idx = (int)tv_get_number_chk(&argvars[1], NULL); - } - // -1 on type error - rettv->vval.v_string = (char *)vim_strsave(get_history_entry(type, idx)); - } - rettv->v_type = VAR_STRING; -} - -/// "histnr()" function -static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - const char *const history = tv_get_string_chk(&argvars[0]); - HistoryType i = history == NULL - ? HIST_INVALID - : get_histtype(history, strlen(history), false); - if (i != HIST_INVALID) { - i = get_history_idx(i); - } - rettv->vval.v_number = i; -} - /// "highlightID(name)" function static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -4526,21 +4070,18 @@ static bool inputsecret_flag = false; /// Also handles inputsecret() when inputsecret is set. static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - get_user_input(argvars, rettv, FALSE, inputsecret_flag); + get_user_input(argvars, rettv, false, inputsecret_flag); } /// "inputdialog()" function static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - get_user_input(argvars, rettv, TRUE, inputsecret_flag); + get_user_input(argvars, rettv, true, inputsecret_flag); } /// "inputlist()" function static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int selected; - int mouse_used; - if (argvars[0].v_type != VAR_LIST) { semsg(_(e_listarg), "inputlist()"); return; @@ -4558,7 +4099,8 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) }); // Ask for choice. - selected = prompt_for_number(&mouse_used); + int mouse_used; + int selected = prompt_for_number(&mouse_used); if (mouse_used) { selected -= lines_left; } @@ -4695,7 +4237,6 @@ static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) { lval_T lv; - dictitem_T *di; rettv->vval.v_number = -1; const char_u *const end = (char_u *)get_lval((char *)tv_get_string(&argvars[0]), @@ -4708,7 +4249,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) semsg(_(e_trailing_arg), end); } else { if (lv.ll_tv == NULL) { - di = find_var(lv.ll_name, lv.ll_name_len, NULL, true); + dictitem_T *di = find_var(lv.ll_name, lv.ll_name_len, NULL, true); if (di != NULL) { // Consider a variable locked when: // 1. the variable itself is locked @@ -5016,7 +4557,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (new_cwd && *new_cwd != NUL) { cwd = new_cwd; // The new cwd must be a directory. - if (!os_isdir_executable((const char *)cwd)) { + if (!os_isdir((const char_u *)cwd)) { semsg(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; @@ -5410,7 +4951,7 @@ static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "map()" function static void f_map(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - filter_map(argvars, rettv, TRUE); + filter_map(argvars, rettv, true); } static void find_some_match(typval_T *const argvars, typval_T *const rettv, @@ -5420,18 +4961,16 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, long len = 0; char_u *expr = NULL; regmatch_T regmatch; - char *save_cpo; long start = 0; long nth = 1; colnr_T startcol = 0; bool match = false; list_T *l = NULL; - listitem_T *li = NULL; long idx = 0; char_u *tofree = NULL; // Make 'cpoptions' empty, the 'l' flag should not be used here. - save_cpo = p_cpo; + char *save_cpo = p_cpo; p_cpo = ""; rettv->vval.v_number = -1; @@ -5458,6 +4997,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, break; } + listitem_T *li = NULL; if (argvars[0].v_type == VAR_LIST) { if ((l = argvars[0].vval.v_list) == NULL) { goto theend; @@ -5566,10 +5106,8 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, const size_t rd = (size_t)(regmatch.endp[0] - regmatch.startp[0]); TV_LIST_ITEM_TV(li1)->vval.v_string = xmemdupz((const char *)regmatch.startp[0], rd); - TV_LIST_ITEM_TV(li3)->vval.v_number = (varnumber_T)( - regmatch.startp[0] - expr); - TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)( - regmatch.endp[0] - expr); + TV_LIST_ITEM_TV(li3)->vval.v_number = (varnumber_T)(regmatch.startp[0] - expr); + TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)(regmatch.endp[0] - expr); if (l != NULL) { TV_LIST_ITEM_TV(li2)->vval.v_number = (varnumber_T)idx; } @@ -5710,13 +5248,13 @@ static void max_min(const typval_T *const tv, typval_T *const rettv, const bool /// "max()" function static void f_max(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - max_min(argvars, rettv, TRUE); + max_min(argvars, rettv, true); } /// "min()" function static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - max_min(argvars, rettv, FALSE); + max_min(argvars, rettv, false); } /// "mkdir()" function @@ -6047,14 +5585,13 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; { - int len; int saved_did_emsg = did_emsg; // Get the required length, allocate the buffer and do it for real. did_emsg = false; char buf[NUMBUFLEN]; const char *fmt = tv_get_string_buf(&argvars[0], buf); - len = vim_vsnprintf_typval(NULL, 0, fmt, dummy_ap, argvars + 1); + int len = vim_vsnprintf_typval(NULL, 0, fmt, dummy_ap, argvars + 1); if (!did_emsg) { char *s = xmalloc((size_t)len + 1); rettv->vval.v_string = s; @@ -6067,13 +5604,12 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "prompt_setcallback({buffer}, {callback})" function static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - buf_T *buf; Callback prompt_callback = { .type = kCallbackNone }; if (check_secure()) { return; } - buf = tv_get_buf(&argvars[0], false); + buf_T *buf = tv_get_buf(&argvars[0], false); if (buf == NULL) { return; } @@ -6091,13 +5627,12 @@ static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr /// "prompt_setinterrupt({buffer}, {callback})" function static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - buf_T *buf; Callback interrupt_callback = { .type = kCallbackNone }; if (check_secure()) { return; } - buf = tv_get_buf(&argvars[0], false); + buf_T *buf = tv_get_buf(&argvars[0], false); if (buf == NULL) { return; } @@ -6342,13 +5877,11 @@ static void f_rubyeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "range()" function static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - varnumber_T start; varnumber_T end; varnumber_T stride = 1; - varnumber_T i; bool error = false; - start = tv_get_number_chk(&argvars[0], &error); + varnumber_T start = tv_get_number_chk(&argvars[0], &error); if (argvars[1].v_type == VAR_UNKNOWN) { end = start - 1; start = 0; @@ -6368,7 +5901,7 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) emsg(_("E727: Start past end")); } else { tv_list_alloc_ret(rettv, (end - start) / stride); - for (i = start; stride > 0 ? i <= end : i >= end; i += stride) { + for (varnumber_T i = start; stride > 0 ? i <= end : i >= end; i += stride) { tv_list_append_number(rettv->vval.v_list, i); } } @@ -6379,8 +5912,6 @@ static varnumber_T readdir_checkitem(void *context, const char *name) FUNC_ATTR_NONNULL_ALL { typval_T *expr = (typval_T *)context; - typval_T save_val; - typval_T rettv; typval_T argv[2]; varnumber_T retval = 0; bool error = false; @@ -6389,11 +5920,13 @@ static varnumber_T readdir_checkitem(void *context, const char *name) return 1; } + typval_T save_val; prepare_vimvar(VV_VAL, &save_val); set_vim_var_string(VV_VAL, name, -1); argv[0].v_type = VAR_STRING; argv[0].vval.v_string = (char *)name; + typval_T rettv; if (eval_expr_typval(expr, argv, 1, &rettv) == FAIL) { goto theend; } @@ -6435,12 +5968,11 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool binary = false; bool blob = false; FILE *fd; - char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1 + char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1 int io_size = sizeof(buf); - int readlen; // size of last fread() - char_u *prev = NULL; // previously read bytes, if any - long prevlen = 0; // length of data in prev - long prevsize = 0; // size of prev buffer + char_u *prev = NULL; // previously read bytes, if any + long prevlen = 0; // length of data in prev + long prevsize = 0; // size of prev buffer long maxline = MAXLNUM; if (argvars[1].v_type != VAR_UNKNOWN) { @@ -6482,7 +6014,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) list_T *const l = tv_list_alloc_ret(rettv, kListLenUnknown); while (maxline < 0 || tv_list_len(l) < maxline) { - readlen = (int)fread(buf, 1, (size_t)io_size, fd); + int readlen = (int)fread(buf, 1, (size_t)io_size, fd); // This for loop processes what was read, but is also entered at end // of file so that either: @@ -6514,9 +6046,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) assert(len < INT_MAX); s = vim_strnsave(start, len); } else { - /* Change "prev" buffer to be the right size. This way - * the bytes are only copied once, and very long lines are - * allocated only once. */ + // Change "prev" buffer to be the right size. This way + // the bytes are only copied once, and very long lines are + // allocated only once. s = xrealloc(prev, (size_t)prevlen + len + 1); memcpy(s + prevlen, start, len); s[(size_t)prevlen + len] = NUL; @@ -6590,10 +6122,10 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (start < p) { // There's part of a line in buf, store it in "prev". if (p - start + prevlen >= prevsize) { - /* A common use case is ordinary text files and "prev" gets a - * fragment of a line, so the first allocation is made - * small, to avoid repeatedly 'allocing' large and - * 'reallocing' small. */ + // A common use case is ordinary text files and "prev" gets a + // fragment of a line, so the first allocation is made + // small, to avoid repeatedly 'allocing' large and + // 'reallocing' small. if (prevsize == 0) { prevsize = (long)(p - start); } else { @@ -7142,7 +6674,6 @@ static void f_reduce(typval_T *argvars, typval_T *rettv, FunPtr fptr) static int get_search_arg(typval_T *varp, int *flagsp) { int dir = FORWARD; - int mask; if (varp->v_type != VAR_UNKNOWN) { char nbuf[NUMBUFLEN]; @@ -7150,6 +6681,7 @@ static int get_search_arg(typval_T *varp, int *flagsp) if (flags == NULL) { return 0; // Type error; errmsg already given. } + int mask; while (*flags != NUL) { switch (*flags) { case 'b': @@ -7199,26 +6731,19 @@ static int get_search_arg(typval_T *varp, int *flagsp) /// Shared by search() and searchpos() functions. static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) { - int flags; - pos_T pos; - pos_T save_cursor; bool save_p_ws = p_ws; - int dir; int retval = 0; // default: FAIL long lnum_stop = 0; - proftime_T tm; long time_limit = 0; int options = SEARCH_KEEP; - int subpatnum; - searchit_arg_T sia; bool use_skip = false; const char *const pat = tv_get_string(&argvars[0]); - dir = get_search_arg(&argvars[1], flagsp); // May set p_ws. + int dir = get_search_arg(&argvars[1], flagsp); // May set p_ws. if (dir == 0) { goto theend; } - flags = *flagsp; + int flags = *flagsp; if (flags & SP_START) { options |= SEARCH_START; } @@ -7245,25 +6770,27 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) } // Set the time limit, if there is one. - tm = profile_setlimit(time_limit); - - /* - * This function does not accept SP_REPEAT and SP_RETCOUNT flags. - * Check to make sure only those flags are set. - * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both - * flags cannot be set. Check for that condition also. - */ + proftime_T tm = profile_setlimit(time_limit); + + // This function does not accept SP_REPEAT and SP_RETCOUNT flags. + // Check to make sure only those flags are set. + // Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both + // flags cannot be set. Check for that condition also. if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) { semsg(_(e_invarg2), tv_get_string(&argvars[1])); goto theend; } - pos = save_cursor = curwin->w_cursor; + pos_T save_cursor; + pos_T pos = save_cursor = curwin->w_cursor; pos_T firstpos = { 0 }; - memset(&sia, 0, sizeof(sia)); - sia.sa_stop_lnum = (linenr_T)lnum_stop; - sia.sa_tm = &tm; + searchit_arg_T sia = { + .sa_stop_lnum = (linenr_T)lnum_stop, + .sa_tm = &tm, + }; + + int subpatnum; // Repeat until {skip} returns false. for (;;) { @@ -7398,8 +6925,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) } sctx_T save_current_sctx; - char *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match; - linenr_T save_sourcing_lnum; + char *save_autocmd_fname, *save_autocmd_match; int save_autocmd_bufnr; funccal_entry_T funccal_entry; @@ -7407,16 +6933,14 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) // If this is called from a provider function, restore the scope // information of the caller. save_current_sctx = current_sctx; - save_sourcing_name = sourcing_name; - save_sourcing_lnum = sourcing_lnum; save_autocmd_fname = autocmd_fname; save_autocmd_match = autocmd_match; save_autocmd_bufnr = autocmd_bufnr; save_funccal(&funccal_entry); current_sctx = provider_caller_scope.script_ctx; - sourcing_name = provider_caller_scope.sourcing_name; - sourcing_lnum = provider_caller_scope.sourcing_lnum; + ga_grow(&exestack, 1); + ((estack_T *)exestack.ga_data)[exestack.ga_len++] = provider_caller_scope.es_entry; autocmd_fname = provider_caller_scope.autocmd_fname; autocmd_match = provider_caller_scope.autocmd_match; autocmd_bufnr = provider_caller_scope.autocmd_bufnr; @@ -7433,8 +6957,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (l_provider_call_nesting) { current_sctx = save_current_sctx; - sourcing_name = save_sourcing_name; - sourcing_lnum = save_sourcing_lnum; + exestack.ga_len--; autocmd_fname = save_autocmd_fname; autocmd_match = save_autocmd_match; autocmd_bufnr = save_autocmd_bufnr; @@ -7568,14 +7091,13 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "screenattr()" function static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int c; - - ScreenGrid *grid; int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; + ScreenGrid *grid; screenchar_adjust(&grid, &row, &col); + int c; if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) { c = -1; } else { @@ -7587,14 +7109,13 @@ static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "screenchar()" function static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int c; - - ScreenGrid *grid; int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; + ScreenGrid *grid; screenchar_adjust(&grid, &row, &col); + int c; if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) { c = -1; } else { @@ -7606,10 +7127,10 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "screenchars()" function static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - ScreenGrid *grid; int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; + ScreenGrid *grid; screenchar_adjust(&grid, &row, &col); if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) { @@ -7640,10 +7161,6 @@ static void f_screencol(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "screenpos({winid}, {lnum}, {col})" function static void f_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - pos_T pos; - int row = 0; - int scol = 0, ccol = 0, ecol = 0; - tv_dict_alloc_ret(rettv); dict_T *dict = rettv->vval.v_dict; @@ -7652,9 +7169,13 @@ static void f_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - pos.lnum = (linenr_T)tv_get_number(&argvars[1]); - pos.col = (colnr_T)tv_get_number(&argvars[2]) - 1; - pos.coladd = 0; + pos_T pos = { + .lnum = (linenr_T)tv_get_number(&argvars[1]), + .col = (colnr_T)tv_get_number(&argvars[2]) - 1, + .coladd = 0 + }; + int row = 0; + int scol = 0, ccol = 0, ecol = 0; textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol, false); tv_dict_add_nr(dict, S_LEN("row"), row); @@ -7722,7 +7243,6 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr) static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) { bool save_p_ws = p_ws; - int dir; int flags = 0; int retval = 0; // default: FAIL long lnum_stop = 0; @@ -7740,7 +7260,7 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) } // Handle the optional fourth argument: flags. - dir = get_search_arg(&argvars[3], &flags); // may set p_ws. + int dir = get_search_arg(&argvars[3], &flags); // may set p_ws. if (dir == 0) { goto theend; } @@ -7834,33 +7354,24 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir long time_limit) FUNC_ATTR_NONNULL_ARG(1, 2, 3) { - char *save_cpo; - char_u *pat, *pat2 = NULL, *pat3 = NULL; long retval = 0; - pos_T pos; - pos_T firstpos; - pos_T foundpos; - pos_T save_cursor; - pos_T save_pos; - int n; int nest = 1; bool use_skip = false; int options = SEARCH_KEEP; - proftime_T tm; // Make 'cpoptions' empty, the 'l' flag should not be used here. - save_cpo = p_cpo; + char *save_cpo = p_cpo; p_cpo = (char *)empty_option; // Set the time limit, if there is one. - tm = profile_setlimit(time_limit); + proftime_T tm = profile_setlimit(time_limit); // Make two search patterns: start/end (pat2, for in nested pairs) and // start/middle/end (pat3, for the top pair). const size_t pat2_len = strlen(spat) + strlen(epat) + 17; - pat2 = xmalloc(pat2_len); + char_u *pat2 = xmalloc(pat2_len); const size_t pat3_len = strlen(spat) + strlen(mpat) + strlen(epat) + 25; - pat3 = xmalloc(pat3_len); + char_u *pat3 = xmalloc(pat3_len); snprintf((char *)pat2, pat2_len, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); if (*mpat == NUL) { STRCPY(pat3, pat2); @@ -7876,19 +7387,21 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir use_skip = eval_expr_valid_arg(skip); } - save_cursor = curwin->w_cursor; - pos = curwin->w_cursor; + pos_T save_cursor = curwin->w_cursor; + pos_T pos = curwin->w_cursor; + pos_T firstpos; clearpos(&firstpos); + pos_T foundpos; clearpos(&foundpos); - pat = pat3; + char_u *pat = pat3; for (;;) { - searchit_arg_T sia; - memset(&sia, 0, sizeof(sia)); - sia.sa_stop_lnum = lnum_stop; - sia.sa_tm = &tm; + searchit_arg_T sia = { + .sa_stop_lnum = lnum_stop, + .sa_tm = &tm, + }; - n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L, - options, RE_SEARCH, &sia); + int n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L, + options, RE_SEARCH, &sia); if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) { // didn't find it or found the first match again: FAIL break; @@ -7914,7 +7427,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir // If the skip pattern matches, ignore this match. if (use_skip) { - save_pos = curwin->w_cursor; + pos_T save_pos = curwin->w_cursor; curwin->w_cursor = pos; bool err = false; const bool r = eval_expr_to_bool(skip, &err); @@ -8103,13 +7616,13 @@ static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Otherwise use the column number as a byte offset. static void set_position(typval_T *argvars, typval_T *rettv, bool charpos) { - pos_T pos; - int fnum; colnr_T curswant = -1; rettv->vval.v_number = -1; const char *const name = tv_get_string_chk(argvars); if (name != NULL) { + pos_T pos; + int fnum; if (list2fpos(&argvars[1], &pos, &fnum, &curswant, charpos) == OK) { if (pos.col != MAXCOL && --pos.col < 0) { pos.col = 0; @@ -8143,15 +7656,13 @@ static void f_setcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - dict_T *d; - dictitem_T *di; - if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); return; } - if ((d = argvars[0].vval.v_dict) != NULL) { + dict_T *d = argvars[0].vval.v_dict; + if (d != NULL) { char_u *const csearch = (char_u *)tv_dict_get_string(d, "char", false); if (csearch != NULL) { int pcc[MAX_MCO]; @@ -8159,7 +7670,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) set_last_csearch(c, csearch, utfc_ptr2len((char *)csearch)); } - di = tv_dict_find(d, S_LEN("forward")); + dictitem_T *di = tv_dict_find(d, S_LEN("forward")); if (di != NULL) { set_csearch_direction(tv_get_number(&di->di_tv) ? FORWARD : BACKWARD); } @@ -8240,117 +7751,17 @@ static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr) set_buffer_lines(curbuf, lnum, false, &argvars[1], rettv); } -/// Create quickfix/location list from VimL values -/// -/// Used by `setqflist()` and `setloclist()` functions. Accepts invalid -/// args argument in which case errors out, including VAR_UNKNOWN parameters. -/// -/// @param[in,out] wp Window to create location list for. May be NULL in -/// which case quickfix list will be created. -/// @param[in] args [list, action, what] -/// @param[in] args[0] Quickfix list contents. -/// @param[in] args[1] Optional. Action to perform: -/// append to an existing list, replace its content, -/// or create a new one. -/// @param[in] args[2] Optional. Quickfix list properties or title. -/// Defaults to caller function name. -/// @param[out] rettv Return value: 0 in case of success, -1 otherwise. -static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) - FUNC_ATTR_NONNULL_ARG(2, 3) -{ - static char *e_invact = N_("E927: Invalid action: '%s'"); - const char *title = NULL; - char action = ' '; - static int recursive = 0; - rettv->vval.v_number = -1; - dict_T *what = NULL; - - typval_T *list_arg = &args[0]; - if (list_arg->v_type != VAR_LIST) { - emsg(_(e_listreq)); - return; - } else if (recursive != 0) { - emsg(_(e_au_recursive)); - return; - } - - typval_T *action_arg = &args[1]; - if (action_arg->v_type == VAR_UNKNOWN) { - // Option argument was not given. - goto skip_args; - } else if (action_arg->v_type != VAR_STRING) { - emsg(_(e_stringreq)); - return; - } - const char *const act = tv_get_string_chk(action_arg); - if ((*act == 'a' || *act == 'r' || *act == ' ' || *act == 'f') - && act[1] == NUL) { - action = *act; - } else { - semsg(_(e_invact), act); - return; - } - - typval_T *const what_arg = &args[2]; - if (what_arg->v_type == VAR_UNKNOWN) { - // Option argument was not given. - goto skip_args; - } else if (what_arg->v_type == VAR_STRING) { - title = tv_get_string_chk(what_arg); - if (!title) { - // Type error. Error already printed by tv_get_string_chk(). - return; - } - } else if (what_arg->v_type == VAR_DICT && what_arg->vval.v_dict != NULL) { - what = what_arg->vval.v_dict; - } else { - emsg(_(e_dictreq)); - return; - } - -skip_args: - if (!title) { - title = (wp ? ":setloclist()" : ":setqflist()"); - } - - recursive++; - list_T *const l = list_arg->vval.v_list; - if (set_errorlist(wp, l, action, (char *)title, what) == OK) { - rettv->vval.v_number = 0; - } - recursive--; -} - -/// "setloclist()" function -static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - win_T *win; - - rettv->vval.v_number = -1; - - win = find_win_by_nr_or_id(&argvars[0]); - if (win != NULL) { - set_qf_ll_list(win, &argvars[1], rettv); - } -} - /// "setpos()" function static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) { set_position(argvars, rettv, false); } -/// "setqflist()" function -static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - set_qf_ll_list(NULL, argvars, rettv); -} - /// Translate a register type string to the yank type and block length -static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *const block_len) +static int get_yank_type(char **const pp, MotionType *const yank_type, long *const block_len) FUNC_ATTR_NONNULL_ALL { - char *stropt = (char *)(*pp); + char *stropt = *pp; switch (*stropt) { case 'v': case 'c': // character-wise selection @@ -8372,7 +7783,7 @@ static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *c default: return FAIL; } - *pp = (char_u *)stropt; + *pp = stropt; return OK; } @@ -8380,11 +7791,9 @@ static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *c static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) { bool append = false; - MotionType yank_type; - long block_len; - block_len = -1; - yank_type = kMTUnknown; + long block_len = -1; + MotionType yank_type = kMTUnknown; rettv->vval.v_number = 1; // FAIL is default. @@ -8404,7 +7813,7 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (tv_dict_len(d) == 0) { // Empty dict, clear the register (like setreg(0, [])) - char_u *lstval[2] = { NULL, NULL }; + char *lstval[2] = { NULL, NULL }; write_reg_contents_lst(regname, lstval, false, kMTUnknown, -1); return; } @@ -8416,7 +7825,7 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *stropt = tv_dict_get_string(d, "regtype", false); if (stropt != NULL) { - const int ret = get_yank_type((char_u **)&stropt, &yank_type, &block_len); + const int ret = get_yank_type((char **)&stropt, &yank_type, &block_len); if (ret == FAIL || *(++stropt) != NUL) { semsg(_(e_invargval), "value"); @@ -8459,7 +7868,7 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) set_unnamed = true; break; default: - get_yank_type((char_u **)&stropt, &yank_type, &block_len); + get_yank_type((char **)&stropt, &yank_type, &block_len); } } } @@ -8493,7 +7902,7 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) }); *curval++ = NULL; - write_reg_contents_lst(regname, (char_u **)lstval, append, yank_type, (colnr_T)block_len); + write_reg_contents_lst(regname, lstval, append, yank_type, (colnr_T)block_len); free_lstval: while (curallocval > allocval) { @@ -8523,14 +7932,12 @@ free_lstval: static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) { static char *e_invact2 = N_("E962: Invalid action: '%s'"); - win_T *wp; - dict_T *d; char action = 'r'; rettv->vval.v_number = -1; // first argument: window number or id - wp = find_win_by_nr_or_id(&argvars[0]); + win_T *wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) { return; } @@ -8540,7 +7947,7 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) emsg(_(e_dictreq)); return; } - d = argvars[1].vval.v_dict; + dict_T *d = argvars[1].vval.v_dict; if (d == NULL) { return; } @@ -8600,9 +8007,7 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = 0; if (argvars[0].v_type != VAR_UNKNOWN) { - long col; - - col = (long)tv_get_number_chk(argvars, NULL); + long col = (long)tv_get_number_chk(argvars, NULL); if (col < 0) { return; // type error; errmsg already given } @@ -8681,10 +8086,9 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - bool rpc = false; CallbackReader on_stdin = CALLBACK_READER_INIT; dict_T *opts = argvars[0].vval.v_dict; - rpc = tv_dict_get_number(opts, "rpc") != 0; + bool rpc = tv_dict_get_number(opts, "rpc") != 0; if (!tv_dict_get_callback(opts, S_LEN("on_stdin"), &on_stdin.cb)) { return; @@ -8732,9 +8136,6 @@ static void f_soundfold(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "spellbadword()" function static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - const char *word = ""; - hlf_T attr = HLF_COUNT; - size_t len = 0; const int wo_spell_save = curwin->w_p_spell; if (!curwin->w_p_spell) { @@ -8748,6 +8149,9 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + const char *word = ""; + hlf_T attr = HLF_COUNT; + size_t len = 0; if (argvars[0].v_type == VAR_UNKNOWN) { // Find the start and length of the badly spelled word. len = spell_move_to(curwin, FORWARD, true, true, &attr); @@ -8779,22 +8183,16 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_list_alloc_ret(rettv, 2); tv_list_append_string(rettv->vval.v_list, word, (ssize_t)len); tv_list_append_string(rettv->vval.v_list, - (attr == HLF_SPB ? "bad" - : attr == HLF_SPR ? "rare" - : attr == HLF_SPL ? "local" - : attr == - HLF_SPC ? "caps" - : - NULL), -1); + (attr == HLF_SPB ? "bad" : + attr == HLF_SPR ? "rare" : + attr == HLF_SPL ? "local" : + attr == HLF_SPC ? "caps" : NULL), -1); } /// "spellsuggest()" function static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - bool typeerr = false; - int maxcount; garray_T ga = GA_EMPTY_INIT_VALUE; - bool need_capital = false; const int wo_spell_save = curwin->w_p_spell; if (!curwin->w_p_spell) { @@ -8808,8 +8206,11 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + int maxcount; + bool need_capital = false; const char *const str = tv_get_string(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) { + bool typeerr = false; maxcount = (int)tv_get_number_chk(&argvars[1], &typeerr); if (maxcount <= 0) { goto f_spellsuggest_return; @@ -8838,14 +8239,12 @@ f_spellsuggest_return: static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char *save_cpo; - int match; colnr_T col = 0; bool keepempty = false; bool typeerr = false; // Make 'cpoptions' empty, the 'l' flag should not be used here. - save_cpo = p_cpo; + char *save_cpo = p_cpo; p_cpo = ""; const char *str = tv_get_string(&argvars[0]); @@ -8878,6 +8277,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) }; if (regmatch.regprog != NULL) { while (*str != NUL || keepempty) { + bool match; if (*str == NUL) { match = false; // Empty item at the end. } else { @@ -8978,7 +8378,6 @@ static void f_str2list(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { int base = 10; - varnumber_T n; int what = 0; if (argvars[1].v_type != VAR_UNKNOWN) { @@ -9008,6 +8407,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) what |= STR2NR_HEX | STR2NR_FORCE; break; } + varnumber_T n; vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, false); // Text after the number is silently ignored. if (isneg) { @@ -9583,7 +8983,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) const linenr_T lnum = tv_get_lnum(argvars); const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1; - memset(str, NUL, sizeof(str)); + CLEAR_FIELD(str); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count && col >= 0 && (size_t)col <= STRLEN(ml_get(lnum)) && curwin->w_p_cole > 0) { @@ -9694,11 +9094,9 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Common code for tabpagewinnr() and winnr(). static int get_winnr(tabpage_T *tp, typval_T *argvar) { - win_T *twin; int nr = 1; - win_T *wp; - twin = (tp == curtab) ? curwin : tp->tp_curwin; + win_T *twin = (tp == curtab) ? curwin : tp->tp_curwin; if (argvar->v_type != VAR_UNKNOWN) { bool invalid_arg = false; const char *const arg = tv_get_string_chk(argvar); @@ -9713,20 +9111,20 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar) } } else { // Extract the window count (if specified). e.g. winnr('3j') - char_u *endp; - long count = strtol((char *)arg, (char **)&endp, 10); + char *endp; + long count = strtol((char *)arg, &endp, 10); if (count <= 0) { // if count is not specified, default to 1 count = 1; } if (endp != NULL && *endp != '\0') { - if (strequal((char *)endp, "j")) { + if (strequal(endp, "j")) { twin = win_vert_neighbor(tp, twin, false, count); - } else if (strequal((char *)endp, "k")) { + } else if (strequal(endp, "k")) { twin = win_vert_neighbor(tp, twin, true, count); - } else if (strequal((char *)endp, "h")) { + } else if (strequal(endp, "h")) { twin = win_horz_neighbor(tp, twin, true, count); - } else if (strequal((char *)endp, "l")) { + } else if (strequal(endp, "l")) { twin = win_horz_neighbor(tp, twin, false, count); } else { invalid_arg = true; @@ -9743,14 +9141,14 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar) } if (nr > 0) { - for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; + for (win_T *wp = (tp == curtab) ? firstwin : tp->tp_firstwin; wp != twin; wp = wp->w_next) { if (wp == NULL) { // didn't find it in this tabpage nr = 0; break; } - ++nr; + nr++; } } return nr; @@ -9772,13 +9170,11 @@ static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "tagfiles()" function static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char *fname; - tagname_T tn; - tv_list_alloc_ret(rettv, kListLenUnknown); - fname = xmalloc(MAXPATHL); + char *fname = xmalloc(MAXPATHL); bool first = true; + tagname_T tn; while (get_tagfname(&tn, first, (char_u *)fname) == OK) { tv_list_append_string(rettv->vval.v_list, fname, -1); first = false; @@ -9857,7 +9253,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (new_cwd && *new_cwd != NUL) { cwd = new_cwd; // The new cwd must be a directory. - if (!os_isdir_executable(cwd)) { + if (!os_isdir((const char_u *)cwd)) { semsg(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; @@ -9978,7 +9374,6 @@ static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr) static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) { int repeat = 1; - dict_T *dict; rettv->vval.v_number = -1; if (check_secure()) { @@ -9986,8 +9381,8 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (argvars[2].v_type != VAR_UNKNOWN) { - if (argvars[2].v_type != VAR_DICT - || (dict = argvars[2].vval.v_dict) == NULL) { + dict_T *dict = argvars[2].vval.v_dict; + if (argvars[2].v_type != VAR_DICT || dict == NULL) { semsg(_(e_invarg2), tv_get_string(&argvars[2])); return; } @@ -10128,10 +9523,8 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) char buf2[NUMBUFLEN]; const char_u *head = (const char_u *)tv_get_string_buf_chk(&argvars[0], buf1); const char_u *mask = NULL; - const char_u *tail; const char_u *prev; const char_u *p; - int c1; int dir = 0; rettv->v_type = VAR_STRING; @@ -10156,6 +9549,7 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } + int c1; if (dir == 0 || dir == 1) { // Trim leading characters while (*head != NUL) { @@ -10178,7 +9572,7 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - tail = head + STRLEN(head); + const char_u *tail = head + STRLEN(head); if (dir == 0 || dir == 2) { // Trim trailing characters for (; tail > head; tail = prev) { @@ -10277,10 +9671,9 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr) { colnr_T vcol = 0; - pos_T *fp; int fnum = curbuf->b_fnum; - fp = var2fpos(&argvars[0], false, &fnum, false); + pos_T *fp = var2fpos(&argvars[0], false, &fnum, false); if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count && fnum == curbuf->b_fnum) { // Limit the column to a valid value, getvvcol() doesn't check. @@ -10293,7 +9686,7 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } getvvcol(curwin, fp, NULL, NULL, &vcol); - ++vcol; + vcol++; } rettv->vval.v_number = vcol; @@ -10384,17 +9777,14 @@ static void f_win_id2win(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "win_move_separator()" function static void f_win_move_separator(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - win_T *wp; - int offset; - rettv->vval.v_number = false; - wp = find_win_by_nr_or_id(&argvars[0]); + win_T *wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL || wp->w_floating) { return; } - offset = (int)tv_get_number(&argvars[1]); + int offset = (int)tv_get_number(&argvars[1]); win_drag_vsep_line(wp, offset); rettv->vval.v_number = true; } @@ -10475,18 +9865,15 @@ static void f_winline(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "winnr()" function static void f_winnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int nr = 1; - - nr = get_winnr(curtab, &argvars[0]); - rettv->vval.v_number = nr; + rettv->vval.v_number = get_winnr(curtab, &argvars[0]); } /// "winrestcmd()" function static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - garray_T ga; char_u buf[50]; + garray_T ga; ga_init(&ga, (int)sizeof(char), 70); // Do this twice to handle some window layouts properly. @@ -10511,10 +9898,9 @@ static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "winrestview()" function static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - dict_T *dict; + dict_T *dict = argvars[0].vval.v_dict; - if (argvars[0].v_type != VAR_DICT - || (dict = argvars[0].vval.v_dict) == NULL) { + if (argvars[0].v_type != VAR_DICT || dict == NULL) { emsg(_(e_invarg)); } else { dictitem_T *di; @@ -10562,10 +9948,8 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "winsaveview()" function static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - dict_T *dict; - tv_dict_alloc_ret(rettv); - dict = rettv->vval.v_dict; + dict_T *dict = rettv->vval.v_dict; tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)curwin->w_cursor.lnum); tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)curwin->w_cursor.col); diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index ff1808ed91..8822bb0491 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -233,7 +233,7 @@ void tv_list_init_static10(staticList10_T *const sl) #define SL_SIZE ARRAY_SIZE(sl->sl_items) list_T *const l = &sl->sl_list; - memset(sl, 0, sizeof(staticList10_T)); + CLEAR_POINTER(sl); l->lv_first = &sl->sl_items[0]; l->lv_last = &sl->sl_items[SL_SIZE - 1]; l->lv_refcount = DO_NOT_FREE_CNT; @@ -261,7 +261,7 @@ void tv_list_init_static10(staticList10_T *const sl) void tv_list_init_static(list_T *const l) FUNC_ATTR_NONNULL_ALL { - memset(l, 0, sizeof(*l)); + CLEAR_POINTER(l); l->lv_refcount = DO_NOT_FREE_CNT; list_log(l, NULL, NULL, "sinit"); } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index c02351947b..c4bc9f603b 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -13,10 +13,9 @@ #include "nvim/hashtab.h" #include "nvim/lib/queue.h" #include "nvim/macros.h" -#include "nvim/mbyte.h" +#include "nvim/mbyte_defs.h" #include "nvim/message.h" #include "nvim/pos.h" // for linenr_T -#include "nvim/profile.h" // for proftime_T #include "nvim/types.h" #ifdef LOG_LIST_ACTIONS # include "nvim/memory.h" @@ -356,6 +355,8 @@ struct ufunc { ///< used for s: variables int uf_refcount; ///< reference count, see func_name_refcount() funccall_T *uf_scoped; ///< l: local variables for closure + char_u *uf_name_exp; ///< if "uf_name[]" starts with SNR the name with + ///< "<SNR>" as a string, otherwise NULL char_u uf_name[]; ///< Name of function (actual size equals name); ///< can start with <SNR>123_ ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 2f4799db57..c46cb6ba5d 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -12,8 +12,8 @@ #include "nvim/eval/funcs.h" #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/fileio.h" #include "nvim/getchar.h" @@ -21,7 +21,9 @@ #include "nvim/insexpand.h" #include "nvim/lua/executor.h" #include "nvim/os/input.h" +#include "nvim/profile.h" #include "nvim/regexp.h" +#include "nvim/runtime.h" #include "nvim/search.h" #include "nvim/ui.h" #include "nvim/vim.h" @@ -44,7 +46,7 @@ # include "eval/userfunc.c.generated.h" #endif -hashtab_T func_hashtab; +static hashtab_T func_hashtab; // Used by get_func_tv() static garray_T funcargs = GA_EMPTY_INIT_VALUE; @@ -66,13 +68,19 @@ void func_init(void) hash_init(&func_hashtab); } +/// Return the function hash table +hashtab_T *func_tbl_get(void) +{ + return &func_hashtab; +} + /// Get function arguments. -static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs, +static int get_function_args(char **argp, char_u endchar, garray_T *newargs, int *varargs, garray_T *default_args, bool skip) { bool mustend = false; - char_u *arg = *argp; - char_u *p = arg; + char *arg = *argp; + char *p = arg; char_u c; int i; @@ -89,7 +97,7 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, i // Isolate the arguments: "arg1, arg2, ...)" bool any_default = false; - while (*p != endchar) { + while (*p != (char)endchar) { if (p[0] == '.' && p[1] == '.' && p[2] == '.') { if (varargs != NULL) { *varargs = true; @@ -111,44 +119,43 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, i } if (newargs != NULL) { ga_grow(newargs, 1); - c = *p; + c = (char_u)(*p); *p = NUL; - arg = vim_strsave(arg); + arg = xstrdup(arg); // Check for duplicate argument name. for (i = 0; i < newargs->ga_len; i++) { - if (STRCMP(((char_u **)(newargs->ga_data))[i], arg) == 0) { + if (STRCMP(((char **)(newargs->ga_data))[i], arg) == 0) { semsg(_("E853: Duplicate argument name: %s"), arg); xfree(arg); goto err_ret; } } - ((char_u **)(newargs->ga_data))[newargs->ga_len] = arg; + ((char **)(newargs->ga_data))[newargs->ga_len] = arg; newargs->ga_len++; - *p = c; + *p = (char)c; } - if (*skipwhite((char *)p) == '=' && default_args != NULL) { + if (*skipwhite(p) == '=' && default_args != NULL) { typval_T rettv; any_default = true; - p = (char_u *)skipwhite((char *)p) + 1; - p = (char_u *)skipwhite((char *)p); - char_u *expr = p; - if (eval1((char **)&p, &rettv, false) != FAIL) { + p = skipwhite(p) + 1; + p = skipwhite(p); + char_u *expr = (char_u *)p; + if (eval1(&p, &rettv, false) != FAIL) { ga_grow(default_args, 1); // trim trailing whitespace - while (p > expr && ascii_iswhite(p[-1])) { + while (p > (char *)expr && ascii_iswhite(p[-1])) { p--; } - c = *p; + c = (char_u)(*p); *p = NUL; expr = vim_strsave(expr); - ((char_u **)(default_args->ga_data)) - [default_args->ga_len] = expr; + ((char **)(default_args->ga_data))[default_args->ga_len] = (char *)expr; default_args->ga_len++; - *p = c; + *p = (char)c; } else { mustend = true; } @@ -162,15 +169,15 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, i mustend = true; } } - p = (char_u *)skipwhite((char *)p); - if (mustend && *p != endchar) { + p = skipwhite(p); + if (mustend && *p != (char)endchar) { if (!skip) { semsg(_(e_invarg2), *argp); } break; } } - if (*p != endchar) { + if (*p != (char)endchar) { goto err_ret; } p++; // skip "endchar" @@ -213,10 +220,21 @@ char_u *get_lambda_name(void) return name; } +static void set_ufunc_name(ufunc_T *fp, char_u *name) +{ + STRCPY(fp->uf_name, name); + + if (name[0] == K_SPECIAL) { + fp->uf_name_exp = xmalloc(STRLEN(name) + 3); + STRCPY(fp->uf_name_exp, "<SNR>"); + STRCAT(fp->uf_name_exp, fp->uf_name + 3); + } +} + /// Parse a lambda expression and get a Funcref from "*arg". /// /// @return OK or FAIL. Returns NOTDONE for dict or {expr}. -int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) +int get_lambda_tv(char **arg, typval_T *rettv, bool evaluate) { garray_T newargs = GA_EMPTY_INIT_VALUE; garray_T *pnewargs; @@ -224,13 +242,13 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) partial_T *pt = NULL; int varargs; int ret; - char_u *start = (char_u *)skipwhite((char *)(*arg) + 1); + char_u *start = (char_u *)skipwhite(*arg + 1); char_u *s, *e; bool *old_eval_lavars = eval_lavars_used; bool eval_lavars = false; // First, check if this is a lambda expression. "->" must exists. - ret = get_function_args(&start, '-', NULL, NULL, NULL, true); + ret = get_function_args((char **)&start, '-', NULL, NULL, NULL, true); if (ret == FAIL || *start != '>') { return NOTDONE; } @@ -241,7 +259,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) } else { pnewargs = NULL; } - *arg = (char_u *)skipwhite((char *)(*arg) + 1); + *arg = skipwhite(*arg + 1); ret = get_function_args(arg, '-', pnewargs, &varargs, NULL, false); if (ret == FAIL || **arg != '>') { goto errret; @@ -253,14 +271,14 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) } // Get the start and the end of the expression. - *arg = (char_u *)skipwhite((char *)(*arg) + 1); - s = *arg; - ret = skip_expr((char **)arg); + *arg = skipwhite((*arg) + 1); + s = (char_u *)(*arg); + ret = skip_expr(arg); if (ret == FAIL) { goto errret; } - e = *arg; - *arg = (char_u *)skipwhite((char *)(*arg)); + e = (char_u *)(*arg); + *arg = skipwhite(*arg); if (**arg != '}') { goto errret; } @@ -282,7 +300,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) // Add "return " before the expression. size_t len = (size_t)(7 + e - s + 1); p = (char_u *)xmalloc(len); - ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p; + ((char **)(newlines.ga_data))[newlines.ga_len++] = (char *)p; STRCPY(p, "return "); STRLCPY(p + 7, s, e - s + 1); if (strstr((char *)p + 7, "a:") == NULL) { @@ -291,7 +309,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) } fp->uf_refcount = 1; - STRCPY(fp->uf_name, name); + set_ufunc_name(fp, name); hash_add(&func_hashtab, UF2HIKEY(fp)); fp->uf_args = newargs; ga_init(&fp->uf_def_args, (int)sizeof(char_u *), 1); @@ -313,7 +331,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate) fp->uf_flags = flags; fp->uf_calls = 0; fp->uf_script_ctx = current_sctx; - fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len; + fp->uf_script_ctx.sc_lnum += SOURCING_LNUM - newlines.ga_len; pt->pt_func = fp; pt->pt_refcount = 1; @@ -411,34 +429,32 @@ void emsg_funcname(char *ermsg, const char_u *name) /// @param funcexe various values /// /// @return OK or FAIL. -int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe) +int get_func_tv(const char_u *name, int len, typval_T *rettv, char **arg, funcexe_T *funcexe) { - char_u *argp; + char *argp; int ret = OK; typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments int argcount = 0; // number of arguments found - /* - * Get the arguments. - */ + // Get the arguments. argp = *arg; while (argcount < MAX_FUNC_ARGS - (funcexe->partial == NULL ? 0 : funcexe->partial->pt_argc)) { - argp = (char_u *)skipwhite((char *)argp + 1); // skip the '(' or ',' + argp = skipwhite(argp + 1); // skip the '(' or ',' if (*argp == ')' || *argp == ',' || *argp == NUL) { break; } - if (eval1((char **)&argp, &argvars[argcount], funcexe->evaluate) == FAIL) { + if (eval1(&argp, &argvars[argcount], funcexe->evaluate) == FAIL) { ret = FAIL; break; } - ++argcount; + argcount++; if (*argp != ',') { break; } } if (*argp == ')') { - ++argp; + argp++; } else { ret = FAIL; } @@ -472,7 +488,7 @@ int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, func tv_clear(&argvars[argcount]); } - *arg = (char_u *)skipwhite((char *)argp); + *arg = skipwhite(argp); return ret; } @@ -740,6 +756,7 @@ static void func_clear_items(ufunc_T *fp) ga_clear_strings(&(fp->uf_args)); ga_clear_strings(&(fp->uf_def_args)); ga_clear_strings(&(fp->uf_lines)); + XFREE_CLEAR(fp->uf_name_exp); if (fp->uf_cb_free != NULL) { fp->uf_cb_free(fp->uf_cb_state); @@ -803,8 +820,6 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett linenr_T firstline, linenr_T lastline, dict_T *selfdict) FUNC_ATTR_NONNULL_ARG(1, 3, 4) { - char_u *save_sourcing_name; - linenr_T save_sourcing_lnum; bool using_sandbox = false; funccall_T *fc; int save_did_emsg; @@ -814,7 +829,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett int ai; bool islambda = false; char_u numbuf[NUMBUFLEN]; - char_u *name; + char *name; typval_T *tv_to_free[MAX_FUNC_ARGS]; int tv_to_free_len = 0; proftime_T wait_start; @@ -830,7 +845,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett rettv->vval.v_number = -1; return; } - ++depth; + depth++; // Save search patterns and redo buffer. save_search_patterns(); if (!ins_compl_active()) { @@ -870,7 +885,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // some compiler that checks the destination size. v = (dictitem_T *)&fc->fixvar[fixvar_idx++]; #ifndef __clang_analyzer__ - name = v->di_key; + name = (char *)v->di_key; STRCPY(name, "self"); #endif v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; @@ -896,7 +911,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // destination size. v = (dictitem_T *)&fc->fixvar[fixvar_idx++]; #ifndef __clang_analyzer__ - name = v->di_key; + name = (char *)v->di_key; STRCPY(name, "000"); #endif v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; @@ -935,13 +950,13 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // evaluate named argument default expression isdefault = ai + fp->uf_def_args.ga_len >= 0 && i >= argcount; if (isdefault) { - char_u *default_expr = NULL; + char *default_expr = NULL; def_rettv.v_type = VAR_NUMBER; def_rettv.vval.v_number = -1; - default_expr = ((char_u **)(fp->uf_def_args.ga_data)) + default_expr = ((char **)(fp->uf_def_args.ga_data)) [ai + fp->uf_def_args.ga_len]; - if (eval1((char **)&default_expr, &def_rettv, true) == FAIL) { + if (eval1(&default_expr, &def_rettv, true) == FAIL) { default_arg_err = true; break; } @@ -953,7 +968,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett } // "..." argument a:1, a:2, etc. snprintf((char *)numbuf, sizeof(numbuf), "%d", ai + 1); - name = numbuf; + name = (char *)numbuf; } if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) { v = (dictitem_T *)&fc->fixvar[fixvar_idx++]; @@ -994,73 +1009,49 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // Don't redraw while executing the function. RedrawingDisabled++; - save_sourcing_name = (char_u *)sourcing_name; - save_sourcing_lnum = sourcing_lnum; - sourcing_lnum = 1; if (fp->uf_flags & FC_SANDBOX) { using_sandbox = true; sandbox++; } - // need space for new sourcing_name: - // * save_sourcing_name - // * "["number"].." or "function " - // * "<SNR>" + fp->uf_name - 3 - // * terminating NUL - size_t len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name)) - + STRLEN(fp->uf_name) + 27; - sourcing_name = xmalloc(len); - { - if (save_sourcing_name != NULL - && STRNCMP(save_sourcing_name, "function ", 9) == 0) { - vim_snprintf(sourcing_name, - len, - "%s[%" PRId64 "]..", - save_sourcing_name, - (int64_t)save_sourcing_lnum); - } else { - STRCPY(sourcing_name, "function "); - } - cat_func_name((char_u *)sourcing_name + STRLEN(sourcing_name), fp); - - if (p_verbose >= 12) { - ++no_wait_return; - verbose_enter_scroll(); + estack_push_ufunc(fp, 1); + if (p_verbose >= 12) { + no_wait_return++; + verbose_enter_scroll(); - smsg(_("calling %s"), sourcing_name); - if (p_verbose >= 14) { - msg_puts("("); - for (int i = 0; i < argcount; i++) { - if (i > 0) { - msg_puts(", "); - } - if (argvars[i].v_type == VAR_NUMBER) { - msg_outnum((long)argvars[i].vval.v_number); - } else { - // Do not want errors such as E724 here. - emsg_off++; - char *tofree = encode_tv2string(&argvars[i], NULL); - emsg_off--; - if (tofree != NULL) { - char *s = tofree; - char buf[MSG_BUF_LEN]; - if (vim_strsize(s) > MSG_BUF_CLEN) { - trunc_string(s, buf, MSG_BUF_CLEN, sizeof(buf)); - s = buf; - } - msg_puts(s); - xfree(tofree); + smsg(_("calling %s"), SOURCING_NAME); + if (p_verbose >= 14) { + msg_puts("("); + for (int i = 0; i < argcount; i++) { + if (i > 0) { + msg_puts(", "); + } + if (argvars[i].v_type == VAR_NUMBER) { + msg_outnum((long)argvars[i].vval.v_number); + } else { + // Do not want errors such as E724 here. + emsg_off++; + char *tofree = encode_tv2string(&argvars[i], NULL); + emsg_off--; + if (tofree != NULL) { + char *s = tofree; + char buf[MSG_BUF_LEN]; + if (vim_strsize(s) > MSG_BUF_CLEN) { + trunc_string(s, buf, MSG_BUF_CLEN, sizeof(buf)); + s = buf; } + msg_puts(s); + xfree(tofree); } } - msg_puts(")"); } - msg_puts("\n"); // don't overwrite this either - - verbose_leave_scroll(); - --no_wait_return; + msg_puts(")"); } + msg_puts("\n"); // don't overwrite this either + + verbose_leave_scroll(); + no_wait_return--; } const bool do_profiling_yes = do_profiling == PROF_YES; @@ -1097,12 +1088,12 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett if (default_arg_err && (fp->uf_flags & FC_ABORT)) { did_emsg = true; } else if (islambda) { - char_u *p = *(char_u **)fp->uf_lines.ga_data + 7; + char *p = *(char **)fp->uf_lines.ga_data + 7; // A Lambda always has the command "return {expr}". It is much faster // to evaluate {expr} directly. ex_nesting_level++; - (void)eval1((char **)&p, rettv, true); + (void)eval1(&p, rettv, true); ex_nesting_level--; } else { // call do_cmdline() to execute the lines @@ -1110,7 +1101,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); } - --RedrawingDisabled; + RedrawingDisabled--; // when the function was aborted because of an error, return -1 if ((did_emsg @@ -1140,14 +1131,14 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // when being verbose, mention the return value if (p_verbose >= 12) { - ++no_wait_return; + no_wait_return++; verbose_enter_scroll(); if (aborting()) { - smsg(_("%s aborted"), sourcing_name); + smsg(_("%s aborted"), SOURCING_NAME); } else if (fc->rettv->v_type == VAR_NUMBER) { smsg(_("%s returning #%" PRId64 ""), - sourcing_name, (int64_t)fc->rettv->vval.v_number); + SOURCING_NAME, (int64_t)fc->rettv->vval.v_number); } else { char buf[MSG_BUF_LEN]; @@ -1163,19 +1154,17 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); s = buf; } - smsg(_("%s returning %s"), sourcing_name, s); + smsg(_("%s returning %s"), SOURCING_NAME, s); xfree(tofree); } } msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); - --no_wait_return; + no_wait_return--; } - xfree(sourcing_name); - sourcing_name = (char *)save_sourcing_name; - sourcing_lnum = save_sourcing_lnum; + estack_pop(); current_sctx = save_current_sctx; if (do_profiling_yes) { script_prof_restore(&wait_start); @@ -1184,15 +1173,15 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett sandbox--; } - if (p_verbose >= 12 && sourcing_name != NULL) { - ++no_wait_return; + if (p_verbose >= 12 && SOURCING_NAME != NULL) { + no_wait_return++; verbose_enter_scroll(); - smsg(_("continuing in %s"), sourcing_name); + smsg(_("continuing in %s"), SOURCING_NAME); msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); - --no_wait_return; + no_wait_return--; } did_emsg |= save_did_emsg; @@ -1633,9 +1622,8 @@ static void list_func_head(ufunc_T *fp, int indent, bool force) msg_puts(" "); } msg_puts(force ? "function! " : "function "); - if (fp->uf_name[0] == K_SPECIAL) { - msg_puts_attr("<SNR>", HL_ATTR(HLF_8)); - msg_puts((const char *)fp->uf_name + 3); + if (fp->uf_name_exp != NULL) { + msg_puts((const char *)fp->uf_name_exp); } else { msg_puts((const char *)fp->uf_name); } @@ -1691,7 +1679,7 @@ static void list_func_head(ufunc_T *fp, int indent, bool force) /// @param partial return: partial of a FuncRef /// /// @return the function name in allocated memory, or NULL for failure. -char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, partial_T **partial) +char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, partial_T **partial) FUNC_ATTR_NONNULL_ARG(1) { char_u *name = NULL; @@ -1702,13 +1690,13 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, lval_T lv; if (fdp != NULL) { - memset(fdp, 0, sizeof(funcdict_T)); + CLEAR_POINTER(fdp); } - start = *pp; + start = (char_u *)(*pp); // Check for hard coded <SNR>: already translated function ID (from a user // command). - if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA + if ((unsigned char)(*pp)[0] == K_SPECIAL && (unsigned char)(*pp)[1] == KS_EXTRA && (*pp)[2] == KE_SNR) { *pp += 3; len = get_id_len((const char **)pp) + 3; @@ -1742,7 +1730,7 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, semsg(_(e_invarg2), start); } } else { - *pp = (char_u *)find_name_end((char *)start, NULL, NULL, FNE_INCL_BR); + *pp = (char *)find_name_end((char *)start, NULL, NULL, FNE_INCL_BR); } goto theend; } @@ -1756,7 +1744,7 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, } if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) { name = vim_strsave((char_u *)lv.ll_tv->vval.v_string); - *pp = (char_u *)end; + *pp = (char *)end; } else if (lv.ll_tv->v_type == VAR_PARTIAL && lv.ll_tv->vval.v_partial != NULL) { if (is_luafunc(lv.ll_tv->vval.v_partial) && *end == '.') { @@ -1767,10 +1755,10 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, } name = xmallocz((size_t)len); memcpy(name, end + 1, (size_t)len); - *pp = (char_u *)end + 1 + len; + *pp = (char *)end + 1 + len; } else { name = vim_strsave((char_u *)partial_name(lv.ll_tv->vval.v_partial)); - *pp = (char_u *)end; + *pp = (char *)end; } if (partial != NULL) { *partial = lv.ll_tv->vval.v_partial; @@ -1781,7 +1769,7 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, || fdp->fd_newkey == NULL)) { emsg(_(e_funcref)); } else { - *pp = (char_u *)end; + *pp = (char *)end; } name = NULL; } @@ -1790,7 +1778,7 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, if (lv.ll_name == NULL) { // Error found, but continue after the function name. - *pp = (char_u *)end; + *pp = (char *)end; goto theend; } @@ -1803,16 +1791,16 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, name = NULL; } } else if (!(flags & TFN_NO_DEREF)) { - len = (int)(end - *pp); + len = (int)(end - (char_u *)(*pp)); name = deref_func_name((const char *)(*pp), &len, partial, flags & TFN_NO_AUTOLOAD); - if (name == *pp) { + if (name == (char_u *)(*pp)) { name = NULL; } } if (name != NULL) { name = vim_strsave(name); - *pp = (char_u *)end; + *pp = (char *)end; if (STRNCMP(name, "<SNR>", 5) == 0) { // Change "<SNR>" to the byte sequence. name[0] = K_SPECIAL; @@ -1890,7 +1878,7 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, } memmove(name + lead, lv.ll_name, (size_t)len); name[lead + len] = NUL; - *pp = (char_u *)end; + *pp = (char *)end; theend: clear_lval(&lv); @@ -1941,7 +1929,7 @@ void ex_function(exarg_T *eap) todo = (int)func_hashtab.ht_used; for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) { if (!HASHITEM_EMPTY(hi)) { - --todo; + todo--; fp = HI2UF(hi); if (message_filtered(fp->uf_name)) { continue; @@ -1974,7 +1962,7 @@ void ex_function(exarg_T *eap) todo = (int)func_hashtab.ht_used; for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) { if (!HASHITEM_EMPTY(hi)) { - --todo; + todo--; fp = HI2UF(hi); if (!isdigit(*fp->uf_name) && vim_regexec(®match, (char *)fp->uf_name, 0)) { @@ -1986,7 +1974,7 @@ void ex_function(exarg_T *eap) } } if (*p == '/') { - ++p; + p++; } eap->nextcmd = (char *)check_nextcmd(p); return; @@ -2007,7 +1995,7 @@ void ex_function(exarg_T *eap) // s:func script-local function name // g:func global function name, same as "func" p = (char_u *)eap->arg; - name = trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL); + name = trans_function_name((char **)&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL); paren = (vim_strchr((char *)p, '(') != NULL); if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) { /* @@ -2064,7 +2052,7 @@ void ex_function(exarg_T *eap) msg_putchar(' '); } } - msg_prt_line(FUNCLINE(fp, j), false); + msg_prt_line((char_u *)FUNCLINE(fp, j), false); ui_flush(); // show a line at a time os_breakcheck(); } @@ -2108,9 +2096,8 @@ void ex_function(exarg_T *eap) } if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) { int j = (*arg == K_SPECIAL) ? 3 : 0; - while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) - : eval_isnamec(arg[j]))) { - ++j; + while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) : eval_isnamec(arg[j]))) { + j++; } if (arg[j] != NUL) { emsg_funcname((char *)e_invarg2, arg); @@ -2122,7 +2109,7 @@ void ex_function(exarg_T *eap) } } - if (get_function_args(&p, ')', &newargs, &varargs, + if (get_function_args((char **)&p, ')', &newargs, &varargs, &default_args, eap->skip) == FAIL) { goto errret_2; } @@ -2192,7 +2179,7 @@ void ex_function(exarg_T *eap) } // Save the starting line number. - sourcing_lnum_top = sourcing_lnum; + sourcing_lnum_top = SOURCING_LNUM; indent = 2; nesting = 0; @@ -2234,10 +2221,10 @@ void ex_function(exarg_T *eap) ui_ext_cmdline_block_append((size_t)indent, (const char *)theline); } - // Detect line continuation: sourcing_lnum increased more than one. + // Detect line continuation: SOURCING_LNUM increased more than one. sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie); - if (sourcing_lnum < sourcing_lnum_off) { - sourcing_lnum_off -= sourcing_lnum; + if (SOURCING_LNUM < sourcing_lnum_off) { + sourcing_lnum_off -= SOURCING_LNUM; } else { sourcing_lnum_off = 0; } @@ -2315,7 +2302,7 @@ void ex_function(exarg_T *eap) p = (char_u *)skipwhite((char *)p + 1); } p += eval_fname_script((const char *)p); - xfree(trans_function_name(&p, true, 0, NULL, NULL)); + xfree(trans_function_name((char **)&p, true, 0, NULL, NULL)); if (*skipwhite((char *)p) == '(') { nesting++; indent += 2; @@ -2400,12 +2387,12 @@ void ex_function(exarg_T *eap) // allocates 250 bytes per line, this saves 80% on average. The cost // is an extra alloc/free. p = vim_strsave(theline); - ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p; + ((char **)(newlines.ga_data))[newlines.ga_len++] = (char *)p; // Add NULL lines for continuation lines, so that the line count is // equal to the index in the growarray. while (sourcing_lnum_off-- > 0) { - ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; + ((char **)(newlines.ga_data))[newlines.ga_len++] = NULL; } // Check for end of eap->arg. @@ -2454,9 +2441,12 @@ void ex_function(exarg_T *eap) fp = NULL; overwrite = true; } else { - // redefine existing function + char_u *exp_name = fp->uf_name_exp; + // redefine existing function, keep the expanded name XFREE_CLEAR(name); + fp->uf_name_exp = NULL; func_clear_items(fp); + fp->uf_name_exp = exp_name; fp->uf_profiling = false; fp->uf_prof_initialized = false; } @@ -2495,13 +2485,12 @@ void ex_function(exarg_T *eap) // Check that the autoload name matches the script name. int j = FAIL; - if (sourcing_name != NULL) { + if (SOURCING_NAME != NULL) { scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name)); p = (char_u *)vim_strchr((char *)scriptname, '/'); plen = (int)STRLEN(p); - slen = (int)STRLEN(sourcing_name); - if (slen > plen && FNAMECMP(p, - sourcing_name + slen - plen) == 0) { + slen = (int)STRLEN(SOURCING_NAME); + if (slen > plen && FNAMECMP(p, SOURCING_NAME + slen - plen) == 0) { j = OK; } xfree(scriptname); @@ -2536,7 +2525,7 @@ void ex_function(exarg_T *eap) } // insert the new function in the function list - STRCPY(fp->uf_name, name); + set_ufunc_name(fp, name); if (overwrite) { hi = hash_find(&func_hashtab, (char *)name); hi->hi_key = UF2HIKEY(fp); @@ -2628,8 +2617,7 @@ bool function_exists(const char *const name, bool no_deref) if (no_deref) { flag |= TFN_NO_DEREF; } - char *const p = (char *)trans_function_name((char_u **)&nm, false, flag, NULL, - NULL); + char *const p = (char *)trans_function_name((char **)&nm, false, flag, NULL, NULL); nm = (char_u *)skipwhite((char *)nm); // Only accept "funcname", "funcname ", "funcname (..." and @@ -2656,10 +2644,10 @@ char *get_user_func_name(expand_T *xp, int idx) assert(hi); if (done < func_hashtab.ht_used) { if (done++ > 0) { - ++hi; + hi++; } while (HASHITEM_EMPTY(hi)) { - ++hi; + hi++; } fp = HI2UF(hi); @@ -2693,7 +2681,7 @@ void ex_delfunction(exarg_T *eap) funcdict_T fudi; p = (char_u *)eap->arg; - name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); + name = trans_function_name((char **)&p, eap->skip, 0, &fudi, NULL); xfree(fudi.fd_newkey); if (name == NULL) { if (fudi.fd_dict != NULL && !eap->skip) { @@ -2867,7 +2855,7 @@ void ex_return(exarg_T *eap) } if (eap->skip) { - ++emsg_skip; + emsg_skip++; } eap->nextcmd = NULL; @@ -2899,7 +2887,7 @@ void ex_return(exarg_T *eap) } if (eap->skip) { - --emsg_skip; + emsg_skip--; } } @@ -2932,7 +2920,7 @@ void ex_call(exarg_T *eap) return; } - tofree = trans_function_name(&arg, false, TFN_INT, &fudi, &partial); + tofree = trans_function_name((char **)&arg, false, TFN_INT, &fudi, &partial); if (fudi.fd_newkey != NULL) { // Still need to give an error message for missing key. semsg(_(e_dictkey), fudi.fd_newkey); @@ -2987,7 +2975,7 @@ void ex_call(exarg_T *eap) funcexe.evaluate = true; funcexe.partial = partial; funcexe.selfdict = fudi.fd_dict; - if (get_func_tv(name, -1, &rettv, &arg, &funcexe) == FAIL) { + if (get_func_tv(name, -1, &rettv, (char **)&arg, &funcexe) == FAIL) { failed = true; break; } @@ -3145,8 +3133,7 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat) // If breakpoints have been added/deleted need to check for it. if (fcp->dbg_tick != debug_tick) { - fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, - sourcing_lnum); + fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name, SOURCING_LNUM); fcp->dbg_tick = debug_tick; } if (do_profiling == PROF_YES) { @@ -3160,14 +3147,14 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat) } else { // Skip NULL lines (continuation lines). while (fcp->linenr < gap->ga_len - && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) { + && ((char **)(gap->ga_data))[fcp->linenr] == NULL) { fcp->linenr++; } if (fcp->linenr >= gap->ga_len) { retval = NULL; } else { - retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); - sourcing_lnum = fcp->linenr; + retval = (char_u *)xstrdup(((char **)(gap->ga_data))[fcp->linenr++]); + SOURCING_LNUM = fcp->linenr; if (do_profiling == PROF_YES) { func_line_start(cookie); } @@ -3175,11 +3162,10 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat) } // Did we encounter a breakpoint? - if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) { - dbg_breakpoint(fp->uf_name, sourcing_lnum); + if (fcp->breakpoint != 0 && fcp->breakpoint <= SOURCING_LNUM) { + dbg_breakpoint(fp->uf_name, SOURCING_LNUM); // Find next breakpoint. - fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name, - sourcing_lnum); + fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name, SOURCING_LNUM); fcp->dbg_tick = debug_tick; } diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index ed86aaad4a..4b7007aae9 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -4,6 +4,11 @@ #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" +// From user function to hashitem and back. +#define UF2HIKEY(fp) ((fp)->uf_name) +#define HIKEY2UF(p) ((ufunc_T *)(p - offsetof(ufunc_T, uf_name))) +#define HI2UF(hi) HIKEY2UF((hi)->hi_key) + ///< Structure used by trans_function_name() typedef struct { dict_T *fd_dict; ///< Dictionary used. @@ -59,8 +64,8 @@ typedef struct { .basetv = NULL, \ } -#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] -#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] +#define FUNCARG(fp, j) ((char **)(fp->uf_args.ga_data))[j] +#define FUNCLINE(fp, j) ((char **)(fp->uf_lines.ga_data))[j] #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/userfunc.h.generated.h" diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index ea1c3a8c4e..51123e1a85 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -7,6 +7,7 @@ #include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/charset.h" +#include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/encode.h" #include "nvim/eval/funcs.h" @@ -15,8 +16,10 @@ #include "nvim/eval/vars.h" #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" +#include "nvim/ex_eval.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/screen.h" #include "nvim/search.h" #include "nvim/window.h" |