diff options
Diffstat (limited to 'src/nvim/eval')
-rw-r--r-- | src/nvim/eval/decode.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/executor.c | 3 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 1003 | ||||
-rw-r--r-- | src/nvim/eval/funcs.h | 17 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 79 | ||||
-rw-r--r-- | src/nvim/eval/typval.h | 29 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 438 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.h | 14 | ||||
-rw-r--r-- | src/nvim/eval/vars.c | 55 |
9 files changed, 803 insertions, 839 deletions
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 7b975ce775..d585509df4 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -430,7 +430,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len, const char ubuf[] = { t[1], t[2], t[3], t[4] }; t += 4; uvarnumber_T ch; - vim_str2nr((char_u *)ubuf, NULL, NULL, + vim_str2nr(ubuf, NULL, NULL, STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4, true); if (ch == 0) { hasnul = true; @@ -600,7 +600,7 @@ parse_json_number_check: // Convert integer varnumber_T nr; int num_len; - vim_str2nr((char_u *)s, NULL, &num_len, 0, &nr, NULL, (int)(p - s), true); + vim_str2nr(s, NULL, &num_len, 0, &nr, NULL, (int)(p - s), true); if ((int)exp_num_len != num_len) { semsg(_("E685: internal error: while converting number \"%.*s\" " "to integer vim_str2nr consumed %i bytes in place of %zu"), diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index b461456a3a..0e0d0fe696 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -108,8 +108,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *cons const char *tvs = tv_get_string(tv1); char numbuf[NUMBUFLEN]; char *const s = - (char *)concat_str((const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2, - numbuf)); + concat_str(tvs, tv_get_string_buf(tv2, numbuf)); tv_clear(tv1); tv1->v_type = VAR_STRING; tv1->vval.v_string = s; diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 9c3c859771..8c94586fc9 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -234,7 +234,7 @@ int call_internal_method(const char_u *const fname, const int argcount, typval_T return ERROR_NONE; } -/// @return TRUE for a non-zero Number and a non-empty String. +/// @return true for a non-zero Number and a non-empty String. static int non_zero_arg(typval_T *argvars) { return ((argvars[0].v_type == VAR_NUMBER @@ -251,26 +251,25 @@ static int non_zero_arg(typval_T *argvars) /// Some versions of glibc on i386 have an optimization that makes it harder to /// call math functions indirectly from inside an inlined function, causing /// compile-time errors. Avoid `inline` in that case. #3072 -static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void float_op_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { float_T f; - float_T (*function)(float_T) = (float_T (*)(float_T)) fptr; rettv->v_type = VAR_FLOAT; if (tv_get_float_chk(argvars, &f)) { - rettv->vval.v_float = function(f); + rettv->vval.v_float = fptr.float_func(f); } else { rettv->vval.v_float = 0.0; } } -static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void api_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure()) { return; } - ApiDispatchWrapper fn = (ApiDispatchWrapper)fptr; + MsgpackRpcRequestHandler handler = *fptr.api_handler; Array args = ARRAY_DICT_INIT; @@ -279,7 +278,8 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) } Error err = ERROR_INIT; - Object result = fn(VIML_INTERNAL_CALL, args, &err); + Arena res_arena = ARENA_EMPTY; + Object result = handler.fn(VIML_INTERNAL_CALL, args, &res_arena, &err); if (ERROR_SET(&err)) { semsg_multiline((const char *)e_api_error, err.msg); @@ -292,15 +292,19 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_array(args); - api_free_object(result); + if (handler.arena_return) { + arena_mem_free(arena_finish(&res_arena)); + } else { + api_free_object(result); + } api_clear_error(&err); } /// "abs(expr)" function -static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_abs(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type == VAR_FLOAT) { - float_op_wrapper(argvars, rettv, (FunPtr)&fabs); + float_op_wrapper(argvars, rettv, (EvalFuncData){ .float_func = &fabs }); } else { bool error = false; @@ -316,7 +320,7 @@ static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "add(list, item)" function -static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_add(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = 1; // Default: failed. if (argvars[0].v_type == VAR_LIST) { @@ -344,22 +348,21 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "and(expr, expr)" function -static void f_and(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_and(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL) & tv_get_number_chk(&argvars[1], NULL); } /// "api_info()" function -static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_api_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { Dictionary metadata = api_metadata(); (void)object_to_vim(DICTIONARY_OBJ(metadata), rettv, NULL); - api_free_dictionary(metadata); } /// "append(lnum, string/list)" function -static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_append(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const linenr_T lnum = tv_get_lnum(&argvars[0]); @@ -367,7 +370,7 @@ static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "appendbufline(buf, lnum, string/list)" function -static void f_appendbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_appendbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_T *const buf = tv_get_buf(&argvars[0], false); if (buf == NULL) { @@ -379,7 +382,7 @@ static void f_appendbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "atan2()" function -static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_atan2(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { float_T fx; float_T fy; @@ -393,16 +396,16 @@ static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "browse(save, title, initdir, default)" function -static void f_browse(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_browse(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_string = NULL; rettv->v_type = VAR_STRING; } /// "browsedir(title, initdir)" function -static void f_browsedir(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_browsedir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - f_browse(argvars, rettv, NULL); + f_browse(argvars, rettv, fptr); } /// Find a buffer by number or exact name. @@ -420,7 +423,7 @@ static buf_T *find_buffer(typval_T *avar) FOR_ALL_BUFFERS(bp) { if (bp->b_fname != NULL && (path_with_url(bp->b_fname) || bt_nofilename(bp)) - && STRCMP(bp->b_fname, avar->vval.v_string) == 0) { + && strcmp(bp->b_fname, avar->vval.v_string) == 0) { buf = bp; break; } @@ -431,7 +434,7 @@ static buf_T *find_buffer(typval_T *avar) } /// "bufadd(expr)" function -static void f_bufadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_bufadd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char_u *name = (char_u *)tv_get_string(&argvars[0]); @@ -439,13 +442,13 @@ static void f_bufadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "bufexists(expr)" function -static void f_bufexists(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_bufexists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); } /// "buflisted(expr)" function -static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_buflisted(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_T *buf; @@ -454,7 +457,7 @@ static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "bufload(expr)" function -static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr) +static void f_bufload(typval_T *argvars, typval_T *unused, EvalFuncData fptr) { buf_T *buf = get_buf_arg(&argvars[0]); @@ -469,7 +472,7 @@ static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr) } /// "bufloaded(expr)" function -static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_bufloaded(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_T *buf; @@ -478,7 +481,7 @@ static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "bufname(expr)" function -static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_bufname(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const buf_T *buf; rettv->v_type = VAR_STRING; @@ -494,7 +497,7 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "bufnr(expr)" function -static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_bufnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const buf_T *buf; bool error = false; @@ -554,13 +557,13 @@ static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr) } /// "bufwinid(nr)" function -static void f_bufwinid(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_bufwinid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_win_common(argvars, rettv, false); } /// "bufwinnr(nr)" function -static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_bufwinnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_win_common(argvars, rettv, true); } @@ -588,7 +591,7 @@ buf_T *tv_get_buf(typval_T *tv, int curtab_only) int save_magic = p_magic; p_magic = true; char *save_cpo = p_cpo; - p_cpo = ""; + p_cpo = empty_option; buf_T *buf = buflist_findnr(buflist_findpat((char *)name, (char *)name + STRLEN(name), true, false, curtab_only)); @@ -630,7 +633,7 @@ buf_T *get_buf_arg(typval_T *arg) } /// "byte2line(byte)" function -static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_byte2line(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { long boff = tv_get_number(&argvars[0]) - 1; if (boff < 0) { @@ -665,19 +668,19 @@ 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) +static void f_byteidx(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { byteidx(argvars, rettv, false); } /// "byteidxcomp()" function -static void f_byteidxcomp(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_byteidxcomp(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { byteidx(argvars, rettv, true); } /// "call(func, arglist [, dict])" function -static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_call(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[1].v_type != VAR_LIST) { emsg(_(e_listreq)); @@ -726,13 +729,13 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "changenr()" function -static void f_changenr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_changenr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = curbuf->b_u_seq_cur; } /// "chanclose(id[, stream])" function -static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_chanclose(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -771,7 +774,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "chansend(id, data)" function -static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_chansend(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -812,7 +815,7 @@ static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "char2nr(string)" function -static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_char2nr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[1].v_type != VAR_UNKNOWN) { if (!tv_check_num(&argvars[1])) { @@ -846,11 +849,12 @@ static void get_col(typval_T *argvars, typval_T *rettv, bool charcol) // col(".") when the cursor is on the NUL at the end of the line // because of "coladd" can be seen as an extra column. if (virtual_active() && fp == &curwin->w_cursor) { - char_u *p = get_cursor_pos_ptr(); + char *p = get_cursor_pos_ptr(); if (curwin->w_cursor.coladd >= - (colnr_T)win_chartabsize(curwin, p, curwin->w_virtcol - curwin->w_cursor.coladd)) { + (colnr_T)win_chartabsize(curwin, p, + curwin->w_virtcol - curwin->w_cursor.coladd)) { int l; - if (*p != NUL && p[(l = utfc_ptr2len((char *)p))] == NUL) { + if (*p != NUL && p[(l = utfc_ptr2len(p))] == NUL) { col += l; } } @@ -861,20 +865,21 @@ static void get_col(typval_T *argvars, typval_T *rettv, bool charcol) } /// "charcol()" function -static void f_charcol(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_charcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { get_col(argvars, rettv, true); } /// "charidx()" function -static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_charidx(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = -1; if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_NUMBER || (argvars[2].v_type != VAR_UNKNOWN - && argvars[2].v_type != VAR_NUMBER)) { + && argvars[2].v_type != VAR_NUMBER + && argvars[2].v_type != VAR_BOOL)) { emsg(_(e_invarg)); return; } @@ -913,7 +918,7 @@ 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) +static void f_chdir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -925,12 +930,12 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // Return the current directory - char_u *cwd = xmalloc(MAXPATHL); - if (os_dirname(cwd, MAXPATHL) != FAIL) { + char *cwd = xmalloc(MAXPATHL); + if (os_dirname((char_u *)cwd, MAXPATHL) != FAIL) { #ifdef BACKSLASH_IN_FILENAME slash_adjust(cwd); #endif - rettv->vval.v_string = (char *)vim_strsave(cwd); + rettv->vval.v_string = xstrdup(cwd); } xfree(cwd); @@ -948,7 +953,7 @@ 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) +static void f_cindent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { pos_T pos = curwin->w_cursor; linenr_T lnum = tv_get_lnum(argvars); @@ -976,13 +981,13 @@ win_T *get_optional_window(typval_T *argvars, int idx) } /// "col(string)" function -static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_col(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { get_col(argvars, rettv, false); } /// "confirm(message, buttons[, default [, type]])" function -static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_confirm(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char buf[NUMBUFLEN]; char buf2[NUMBUFLEN]; @@ -1029,19 +1034,19 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (!error) { - rettv->vval.v_number = do_dialog(type, NULL, (char_u *)message, (char_u *)buttons, def, NULL, + rettv->vval.v_number = do_dialog(type, NULL, (char *)message, (char *)buttons, def, NULL, false); } } /// "copy()" function -static void f_copy(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_copy(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { var_item_copy(NULL, &argvars[0], rettv, false, 0); } /// "count()" function -static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_count(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { long n = 0; int ic = 0; @@ -1060,7 +1065,7 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) const size_t len = STRLEN(expr); while (*p != NUL) { - if (mb_strnicmp(p, expr, len) == 0) { + if (mb_strnicmp((char *)p, (char *)expr, len) == 0) { n++; p += len; } else { @@ -1130,7 +1135,7 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "cscope_connection([{num} , {dbpath} [, {prepend}]])" function /// /// Checks the existence of a cscope connection. -static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_cscope_connection(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int num = 0; const char *dbpath = NULL; @@ -1151,7 +1156,7 @@ static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "ctxget([{index}])" function -static void f_ctxget(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_ctxget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { size_t index = 0; if (argvars[0].v_type == VAR_NUMBER) { @@ -1175,7 +1180,7 @@ static void f_ctxget(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "ctxpop()" function -static void f_ctxpop(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_ctxpop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (!ctx_restore(NULL, kCtxAll)) { emsg(_("Context stack is empty")); @@ -1183,7 +1188,7 @@ static void f_ctxpop(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "ctxpush([{types}])" function -static void f_ctxpush(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_ctxpush(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int types = kCtxAll; if (argvars[0].v_type == VAR_LIST) { @@ -1214,7 +1219,7 @@ static void f_ctxpush(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "ctxset({context}[, {index}])" function -static void f_ctxset(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_ctxset(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_DICT) { semsg(_(e_invarg2), "expected dictionary as first argument"); @@ -1254,7 +1259,7 @@ static void f_ctxset(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "ctxsize()" function -static void f_ctxsize(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_ctxsize(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = (varnumber_T)ctx_size(); @@ -1326,13 +1331,13 @@ static void set_cursorpos(typval_T *argvars, typval_T *rettv, bool charcol) /// Moves the cursor to the specified line and column. /// /// @return 0 when the position could be set, -1 otherwise. -static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_cursor(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { set_cursorpos(argvars, rettv, false); } /// "debugbreak()" function -static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_debugbreak(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = FAIL; int pid = (int)tv_get_number(&argvars[0]); @@ -1354,7 +1359,7 @@ static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "deepcopy()" function -static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_deepcopy(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int noref = 0; @@ -1371,7 +1376,7 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "delete()" function -static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_delete(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = -1; if (check_secure()) { @@ -1407,7 +1412,7 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// dictwatcheradd(dict, key, funcref) function -static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure()) { return; @@ -1445,7 +1450,7 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// dictwatcherdel(dict, key, funcref) function -static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure()) { return; @@ -1480,7 +1485,7 @@ 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) +static void f_deletebufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_T *const buf = tv_get_buf(&argvars[0], false); if (buf == NULL) { @@ -1556,19 +1561,19 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "did_filetype()" function -static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_did_filetype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = did_filetype; } /// "diff_filler()" function -static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_diff_filler(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = MAX(0, diff_check(curwin, tv_get_lnum(argvars))); } /// "diff_hlID()" function -static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_diff_hlID(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { linenr_T lnum = tv_get_lnum(argvars); static linenr_T prev_lnum = 0; @@ -1618,7 +1623,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "empty({expr})" function -static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_empty(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { bool n = true; @@ -1668,7 +1673,7 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "environ()" function -static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_environ(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_alloc_ret(rettv); @@ -1713,7 +1718,7 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "escape({string}, {chars})" function -static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_escape(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char buf[NUMBUFLEN]; @@ -1724,7 +1729,7 @@ static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getenv()" function -static void f_getenv(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getenv(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char_u *p = (char_u *)vim_getenv(tv_get_string(&argvars[0])); @@ -1738,7 +1743,7 @@ static void f_getenv(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "eval()" function -static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_eval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *s = tv_get_string_chk(&argvars[0]); if (s != NULL) { @@ -1759,15 +1764,15 @@ static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "eventhandler()" function -static void f_eventhandler(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_eventhandler(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = vgetc_busy; } /// "executable()" function -static void f_executable(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_executable(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - if (tv_check_for_string(&argvars[0]) == FAIL) { + if (tv_check_for_string_arg(argvars, 0) == FAIL) { return; } @@ -1794,7 +1799,7 @@ static char *get_list_line(int c, void *cookie, int indent, bool do_concat) return s == NULL ? NULL : xstrdup(s); } -static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int arg_off) +static void execute_common(typval_T *argvars, typval_T *rettv, int arg_off) { const int save_msg_silent = msg_silent; const int save_emsg_silent = emsg_silent; @@ -1873,13 +1878,13 @@ static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int } /// "execute(command)" function -static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_execute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - execute_common(argvars, rettv, fptr, 0); + execute_common(argvars, rettv, 0); } /// "win_execute(win_id, command)" function -static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_execute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // Return an empty string if something fails. rettv->v_type = VAR_STRING; @@ -1889,14 +1894,14 @@ static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) tabpage_T *tp; win_T *wp = win_id2wp_tp(id, &tp); if (wp != NULL && tp != NULL) { - WIN_EXECUTE(wp, tp, execute_common(argvars, rettv, fptr, 1)); + WIN_EXECUTE(wp, tp, execute_common(argvars, rettv, 1)); } } /// "exepath()" function -static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_exepath(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - if (tv_check_for_nonempty_string(&argvars[0]) == FAIL) { + if (tv_check_for_nonempty_string_arg(argvars, 0) == FAIL) { return; } @@ -1915,7 +1920,7 @@ static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "exists()" function -static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_exists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int n = false; @@ -1955,9 +1960,8 @@ 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) +static void f_expand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - char *errormsg; int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; bool error = false; #ifdef BACKSLASH_IN_FILENAME @@ -1977,10 +1981,17 @@ 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++; + if (p_verbose == 0) { + emsg_off++; + } size_t len; - char_u *result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL); - emsg_off--; + char *errormsg = NULL; + char_u *result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL, false); + if (p_verbose == 0) { + emsg_off--; + } else if (errormsg != NULL) { + emsg(errormsg); + } if (rettv->v_type == VAR_LIST) { tv_list_alloc_ret(rettv, (result != NULL)); if (result != NULL) { @@ -2005,10 +2016,9 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) options += WILD_ICASE; } if (rettv->v_type == VAR_STRING) { - rettv->vval.v_string = (char *)ExpandOne(&xpc, (char_u *)s, NULL, options, - WILD_ALL); + rettv->vval.v_string = ExpandOne(&xpc, (char *)s, NULL, options, WILD_ALL); } else { - ExpandOne(&xpc, (char_u *)s, NULL, options, WILD_ALL_KEEP); + ExpandOne(&xpc, (char *)s, NULL, options, WILD_ALL_KEEP); tv_list_alloc_ret(rettv, xpc.xp_numfiles); for (int i = 0; i < xpc.xp_numfiles; i++) { tv_list_append_string(rettv->vval.v_list, @@ -2026,7 +2036,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "menu_get(path [, modes])" function -static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_menu_get(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenMayKnow); int modes = MENU_ALL_MODES; @@ -2039,7 +2049,7 @@ static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "expandcmd()" function /// Expand all the special characters in a command string. -static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_expandcmd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char *errormsg = NULL; @@ -2063,7 +2073,7 @@ 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) +static void f_flatten(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { bool error = false; @@ -2098,7 +2108,7 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "extend(list, list [, idx])" function /// "extend(dict, dict [, action])" function -static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_extend(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const arg_errmsg = N_("extend() argument"); @@ -2174,7 +2184,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "feedkeys()" function -static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_feedkeys(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // This is not allowed in the sandbox. If the commands would still be // executed in the sandbox it would be OK, but it probably happens later, @@ -2195,17 +2205,17 @@ static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "filereadable()" function -static void f_filereadable(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_filereadable(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const p = tv_get_string(&argvars[0]); rettv->vval.v_number = - (*p && !os_isdir((const char_u *)p) && os_file_is_readable(p)); + (*p && !os_isdir(p) && os_file_is_readable(p)); } /// @return 0 for not writable /// 1 for writable file /// 2 for a dir which we have rights to write into. -static void f_filewritable(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_filewritable(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *filename = tv_get_string(&argvars[0]); rettv->vval.v_number = os_file_is_writable(filename); @@ -2214,7 +2224,7 @@ static void f_filewritable(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) { char_u *fresult = NULL; - char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; + char_u *path = *curbuf->b_p_path == NUL ? p_path : (char_u *)curbuf->b_p_path; int count = 1; bool first = true; bool error = false; @@ -2255,7 +2265,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) find_what, (char_u *)curbuf->b_ffname, (find_what == FINDFILE_DIR ? (char_u *)"" - : curbuf->b_p_sua)); + : (char_u *)curbuf->b_p_sua)); first = false; if (fresult != NULL && rettv->v_type == VAR_LIST) { @@ -2270,25 +2280,25 @@ 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) +static void f_filter(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { filter_map(argvars, rettv, false); } /// "finddir({fname}[, {path}[, {count}]])" function -static void f_finddir(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_finddir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { findfilendir(argvars, rettv, FINDFILE_DIR); } /// "findfile({fname}[, {path}[, {count}]])" function -static void f_findfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_findfile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { findfilendir(argvars, rettv, FINDFILE_FILE); } /// "float2nr({float})" function -static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_float2nr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { float_T f; @@ -2304,7 +2314,7 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "fmod()" function -static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_fmod(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { float_T fx; float_T fy; @@ -2318,14 +2328,14 @@ static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "fnameescape({string})" function -static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_fnameescape(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_string = vim_strsave_fnameescape(tv_get_string(&argvars[0]), VSE_NONE); rettv->v_type = VAR_STRING; } /// "fnamemodify({fname}, {mods})" function -static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_fnamemodify(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char_u *fbuf = NULL; size_t len = 0; @@ -2353,21 +2363,21 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "foreground()" function -static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_foreground(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) {} -static void f_funcref(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_funcref(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - common_function(argvars, rettv, true, fptr); + common_function(argvars, rettv, true); } -static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_function(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - common_function(argvars, rettv, false, fptr); + common_function(argvars, rettv, false); } /// "garbagecollect()" function -static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_garbagecollect(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // This is postponed until we are back at the toplevel, because we may be // using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". @@ -2379,7 +2389,7 @@ 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) +static void f_get(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { typval_T *tv = NULL; bool what_is_dict = false; @@ -2426,7 +2436,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) pt = argvars[0].vval.v_partial; } else { CLEAR_FIELD(fref_pt); - fref_pt.pt_name = (char_u *)argvars[0].vval.v_string; + fref_pt.pt_name = argvars[0].vval.v_string; pt = &fref_pt; } @@ -2476,7 +2486,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getbufinfo()" function -static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getbufinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_T *argbuf = NULL; bool filtered = false; @@ -2538,7 +2548,7 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Get line or list of lines from buffer "buf" into "rettv". /// -/// @param retlist if TRUE, then the lines are returned as a Vim List. +/// @param retlist if true, then the lines are returned as a Vim List. /// /// @return range (from start to end) of lines in rettv from the specified /// buffer. @@ -2568,14 +2578,13 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli } } else { rettv->v_type = VAR_STRING; - rettv->vval.v_string = - (char *)((start >= 1 && start <= buf->b_ml.ml_line_count) - ? vim_strsave(ml_get_buf(buf, start, false)) : NULL); + rettv->vval.v_string = ((start >= 1 && start <= buf->b_ml.ml_line_count) + ? xstrdup(ml_get_buf(buf, start, false)) : NULL); } } /// "getbufline()" function -static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_T *const buf = tv_get_buf_from_arg(&argvars[0]); @@ -2588,7 +2597,7 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getchangelist()" function -static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getchangelist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, 2); @@ -2693,13 +2702,13 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos, bool } /// "getcharpos()" function -static void f_getcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getcharpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getpos_both(argvars, rettv, false, true); } /// "getcharsearch()" function -static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getcharsearch(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_alloc_ret(rettv); @@ -2710,42 +2719,8 @@ static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_dict_add_nr(dict, S_LEN("until"), last_csearch_until()); } -/// "getcmdcompltype()" function -static void f_getcmdcompltype(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)get_cmdline_completion(); -} - -/// "getcmdline()" function -static void f_getcmdline(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)get_cmdline_str(); -} - -/// "getcmdpos()" function -static void f_getcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = get_cmdline_pos() + 1; -} - -/// "getcmdscreenpos()" function -static void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->vval.v_number = get_cmdline_screen_pos() + 1; -} - -/// "getcmdtype()" function -static void f_getcmdtype(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - rettv->v_type = VAR_STRING; - rettv->vval.v_string = xmallocz(1); - rettv->vval.v_string[0] = (char)get_cmdline_type(); -} - /// "getcmdwintype()" function -static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -2762,7 +2737,7 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// @pre An argument may not be -1 if preceding arguments are not all -1. /// /// @post The return value will be a string. -static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getcwd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // Possible scope of working directory to return. CdScope scope = kCdScopeInvalid; @@ -2875,14 +2850,14 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getfontname()" function -static void f_getfontname(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getfontname(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; } /// "getfperm({fname})" function -static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getfperm(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char *perm = NULL; char_u flags[] = "rwx"; @@ -2902,7 +2877,7 @@ static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getfsize({fname})" function -static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getfsize(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *fname = tv_get_string(&argvars[0]); @@ -2911,7 +2886,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr) FileInfo file_info; if (os_fileinfo(fname, &file_info)) { uint64_t filesize = os_fileinfo_size(&file_info); - if (os_isdir((const char_u *)fname)) { + if (os_isdir(fname)) { rettv->vval.v_number = 0; } else { rettv->vval.v_number = (varnumber_T)filesize; @@ -2927,7 +2902,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getftime({fname})" function -static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getftime(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *fname = tv_get_string(&argvars[0]); @@ -2940,9 +2915,9 @@ static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getftype({fname})" function -static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getftype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - char_u *type = NULL; + char *type = NULL; char *t; const char *fname = tv_get_string(&argvars[0]); @@ -2968,13 +2943,13 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { t = "other"; } - type = vim_strsave((char_u *)t); + type = xstrdup(t); } - rettv->vval.v_string = (char *)type; + rettv->vval.v_string = type; } /// "getjumplist()" function -static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getjumplist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenMayKnow); win_T *const wp = find_tabwin(&argvars[0], &argvars[1]); @@ -3005,7 +2980,7 @@ static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getline(lnum, [end])" function -static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { linenr_T end; bool retlist; @@ -3023,7 +2998,7 @@ static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getmarklist()" function -static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getmarklist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenMayKnow); @@ -3041,7 +3016,7 @@ 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) +static void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int row = mouse_row; int col = mouse_col; @@ -3082,24 +3057,24 @@ static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getpid()" function -static void f_getpid(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getpid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = os_get_pid(); } /// "getcurpos(string)" function -static void f_getcurpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getcurpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getpos_both(argvars, rettv, true, false); } -static void f_getcursorcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getcursorcharpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getpos_both(argvars, rettv, true, true); } /// "getpos(string)" function -static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getpos_both(argvars, rettv, false, false); } @@ -3109,23 +3084,23 @@ static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// Returns zero on error. static int getreg_get_regname(typval_T *argvars) { - const char_u *strregname; + const char *strregname; if (argvars[0].v_type != VAR_UNKNOWN) { - strregname = (const char_u *)tv_get_string_chk(&argvars[0]); + strregname = tv_get_string_chk(&argvars[0]); if (strregname == NULL) { // type error; errmsg already given return 0; } } else { // Default to v:register - strregname = (char_u *)get_vim_var_str(VV_REG); + strregname = get_vim_var_str(VV_REG); } - return *strregname == 0 ? '"' : *strregname; + return *strregname == 0 ? '"' : utf_ptr2char(strregname); } /// "getreg()" function -static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getreg(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int arg2 = false; bool return_list = false; @@ -3161,7 +3136,7 @@ static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getregtype()" function -static void f_getregtype(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getregtype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // on error return an empty string rettv->v_type = VAR_STRING; @@ -3181,7 +3156,7 @@ static void f_getregtype(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "gettabinfo()" function -static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_gettabinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tabpage_T *tparg = NULL; @@ -3213,7 +3188,7 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "gettagstack()" function -static void f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_gettagstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp = curwin; // default is current window @@ -3230,7 +3205,7 @@ static void f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getwininfo()" function -static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getwininfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wparg = NULL; @@ -3275,7 +3250,7 @@ static void dummy_timer_close_cb(TimeWatcher *tw, void *data) } /// "wait(timeout, condition[, interval])" function -static void f_wait(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_wait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = -1; @@ -3329,7 +3304,7 @@ static void f_wait(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "win_screenpos()" function -static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_screenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, 2); const win_T *const wp = find_win_by_nr_or_id(&argvars[0]); @@ -3376,7 +3351,7 @@ 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) +static void f_win_splitmove(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp = find_win_by_nr_or_id(&argvars[0]); win_T *targetwin = find_win_by_nr_or_id(&argvars[1]); @@ -3414,7 +3389,7 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getwinpos({timeout})" function -static void f_getwinpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getwinpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, 2); tv_list_append_number(rettv->vval.v_list, -1); @@ -3422,19 +3397,19 @@ static void f_getwinpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getwinposx()" function -static void f_getwinposx(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getwinposx(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = -1; } /// "getwinposy()" function -static void f_getwinposy(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getwinposy(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = -1; } /// "glob()" function -static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_glob(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int options = WILD_SILENT|WILD_USE_NL; expand_T xpc; @@ -3464,11 +3439,11 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) options += WILD_ICASE; } if (rettv->v_type == VAR_STRING) { - rettv->vval.v_string = (char *)ExpandOne(&xpc, (char_u *) - tv_get_string(&argvars[0]), NULL, options, - WILD_ALL); + rettv->vval.v_string = ExpandOne(&xpc, (char *) + tv_get_string(&argvars[0]), NULL, options, + WILD_ALL); } else { - ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options, + ExpandOne(&xpc, (char *)tv_get_string(&argvars[0]), NULL, options, WILD_ALL_KEEP); tv_list_alloc_ret(rettv, xpc.xp_numfiles); for (int i = 0; i < xpc.xp_numfiles; i++) { @@ -3483,7 +3458,7 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "globpath()" function -static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_globpath(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int flags = WILD_IGNORE_COMPLETESLASH; // Flags for globpath. bool error = false; @@ -3514,7 +3489,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 *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags); + globpath((char *)tv_get_string(&argvars[0]), (char *)file, &ga, flags); if (rettv->v_type == VAR_STRING) { rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n"); @@ -3533,7 +3508,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "glob2regpat()" function -static void f_glob2regpat(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_glob2regpat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const pat = tv_get_string_chk(&argvars[0]); // NULL on type error @@ -3542,7 +3517,7 @@ static void f_glob2regpat(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "has()" function -static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_has(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { static const char *const has_list[] = { #if defined(BSD) && !defined(__APPLE__) @@ -3660,6 +3635,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) "title", "user-commands", // was accidentally included in 5.4 "user_commands", + "usermarks", "vartabs", "vertsplit", "vimscript-1", @@ -3673,6 +3649,8 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) "winaltkeys", "writebackup", "nvim", + "userreg", + "floattitle", }; // XXX: eval_has_provider() may shell out :( @@ -3764,7 +3742,7 @@ static bool has_wsl(void) /// @pre An argument may not be -1 if preceding arguments are not all -1. /// /// @post The return value will be either the number `1` or `0`. -static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_haslocaldir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // Possible scope of working directory to return. CdScope scope = kCdScopeInvalid; @@ -3854,29 +3832,29 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "highlightID(name)" function -static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_hlID(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = syn_name2id(tv_get_string(&argvars[0])); } /// "highlight_exists()" function -static void f_hlexists(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_hlexists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = highlight_exists(tv_get_string(&argvars[0])); } /// "hostname()" function -static void f_hostname(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_hostname(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char hostname[256]; os_get_hostname(hostname, 256); rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)vim_strsave((char_u *)hostname); + rettv->vval.v_string = xstrdup(hostname); } /// iconv() function -static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_iconv(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { vimconv_T vimconv; @@ -3885,17 +3863,19 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *const str = tv_get_string(&argvars[0]); char buf1[NUMBUFLEN]; - char_u *const from = enc_canonize(enc_skip((char_u *)tv_get_string_buf(&argvars[1], buf1))); + char_u *const from = + (char_u *)enc_canonize(enc_skip((char *)tv_get_string_buf(&argvars[1], buf1))); char buf2[NUMBUFLEN]; - char_u *const to = enc_canonize(enc_skip((char_u *)tv_get_string_buf(&argvars[2], buf2))); + char_u *const to = + (char_u *)enc_canonize(enc_skip((char *)tv_get_string_buf(&argvars[2], buf2))); vimconv.vc_type = CONV_NONE; - convert_setup(&vimconv, from, to); + convert_setup(&vimconv, (char *)from, (char *)to); // If the encodings are equal, no conversion needed. if (vimconv.vc_type == CONV_NONE) { rettv->vval.v_string = xstrdup(str); } else { - rettv->vval.v_string = (char *)string_convert(&vimconv, (char_u *)str, NULL); + rettv->vval.v_string = string_convert(&vimconv, (char *)str, NULL); } convert_setup(&vimconv, NULL, NULL); @@ -3904,7 +3884,7 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "indent()" function -static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_indent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const linenr_T lnum = tv_get_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { @@ -3915,7 +3895,7 @@ static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "index()" function -static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_index(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { long idx = 0; bool ic = false; @@ -3990,19 +3970,19 @@ static bool inputsecret_flag = false; /// "input()" function /// Also handles inputsecret() when inputsecret is set. -static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_input(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { get_user_input(argvars, rettv, false, inputsecret_flag); } /// "inputdialog()" function -static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_inputdialog(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { get_user_input(argvars, rettv, true, inputsecret_flag); } /// "inputlist()" function -static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_inputlist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_LIST) { semsg(_(e_listarg), "inputlist()"); @@ -4033,7 +4013,7 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) static garray_T ga_userinput = { 0, 0, sizeof(tasave_T), 4, NULL }; /// "inputrestore()" function -static void f_inputrestore(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_inputrestore(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (!GA_EMPTY(&ga_userinput)) { ga_userinput.ga_len--; @@ -4047,7 +4027,7 @@ static void f_inputrestore(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "inputsave()" function -static void f_inputsave(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_inputsave(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // Add an entry to the stack of typeahead storage. tasave_T *p = GA_APPEND_VIA_PTR(tasave_T, &ga_userinput); @@ -4055,17 +4035,17 @@ static void f_inputsave(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "inputsecret()" function -static void f_inputsecret(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_inputsecret(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { cmdline_star++; inputsecret_flag = true; - f_input(argvars, rettv, NULL); + f_input(argvars, rettv, fptr); cmdline_star--; inputsecret_flag = false; } /// "insert()" function -static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_insert(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { list_T *l; bool error = false; @@ -4138,25 +4118,25 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "interrupt()" function static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED, typval_T *rettv FUNC_ATTR_UNUSED, - FunPtr fptr FUNC_ATTR_UNUSED) + EvalFuncData fptr FUNC_ATTR_UNUSED) { got_int = true; } /// "invert(expr)" function -static void f_invert(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_invert(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = ~tv_get_number_chk(&argvars[0], NULL); } /// "isdirectory()" function -static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_isdirectory(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - rettv->vval.v_number = os_isdir((const char_u *)tv_get_string(&argvars[0])); + rettv->vval.v_number = os_isdir(tv_get_string(&argvars[0])); } /// "islocked()" function -static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_islocked(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { lval_T lv; @@ -4198,7 +4178,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "isinf()" function -static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_isinf(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type == VAR_FLOAT && xisinf(argvars[0].vval.v_float)) { @@ -4207,14 +4187,14 @@ static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "isnan()" function -static void f_isnan(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_isnan(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT && xisnan(argvars[0].vval.v_float); } /// "id()" function -static void f_id(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_id(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) FUNC_ATTR_NONNULL_ALL { const int len = vim_vsnprintf_typval(NULL, 0, "%p", dummy_ap, argvars); @@ -4224,7 +4204,7 @@ static void f_id(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "jobpid(id)" function -static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_jobpid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -4248,7 +4228,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "jobresize(job, width, height)" function -static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_jobresize(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -4315,7 +4295,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en if (!clear_env) { typval_T temp_env = TV_INITIAL_VALUE; - f_environ(NULL, &temp_env, NULL); + f_environ(NULL, &temp_env, (EvalFuncData){ .nullptr = NULL }); tv_dict_extend(env, temp_env.vval.v_dict, "force"); tv_dict_free(temp_env.vval.v_dict); @@ -4404,7 +4384,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en } /// "jobstart()" function -static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -4479,7 +4459,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((const char_u *)cwd)) { + if (!os_isdir(cwd)) { semsg(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; @@ -4524,7 +4504,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "jobstop()" function -static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_jobstop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -4557,7 +4537,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "jobwait(ids[, timeout])" function -static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_jobwait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -4656,7 +4636,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// json_decode() function -static void f_json_decode(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_json_decode(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char numbuf[NUMBUFLEN]; const char *s = NULL; @@ -4690,14 +4670,14 @@ static void f_json_decode(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// json_encode() function -static void f_json_encode(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_json_encode(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = encode_tv2json(&argvars[0], NULL); } /// "last_buffer_nr()" function. -static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int n = 0; @@ -4711,7 +4691,7 @@ static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "len()" function -static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_len(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { switch (argvars[0].v_type) { case VAR_STRING: @@ -4782,19 +4762,19 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type) } /// "libcall()" function -static void f_libcall(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_libcall(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { libcall_common(argvars, rettv, VAR_STRING); } /// "libcallnr()" function -static void f_libcallnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_libcallnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { libcall_common(argvars, rettv, VAR_NUMBER); } /// "line(string, [winid])" function -static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_line(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { linenr_T lnum = 0; pos_T *fp = NULL; @@ -4825,7 +4805,7 @@ static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "line2byte(lnum)" function -static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_line2byte(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const linenr_T lnum = tv_get_lnum(argvars); if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) { @@ -4839,7 +4819,7 @@ static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "lispindent(lnum)" function -static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_lispindent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const pos_T pos = curwin->w_cursor; const linenr_T lnum = tv_get_lnum(argvars); @@ -4853,13 +4833,13 @@ static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "localtime()" function -static void f_localtime(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_localtime(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = (varnumber_T)time(NULL); } /// luaeval() function implementation -static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_luaeval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) FUNC_ATTR_NONNULL_ALL { const char *const str = tv_get_string_chk(&argvars[0]); @@ -4871,7 +4851,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) +static void f_map(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { filter_map(argvars, rettv, true); } @@ -4893,7 +4873,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, // Make 'cpoptions' empty, the 'l' flag should not be used here. char *save_cpo = p_cpo; - p_cpo = ""; + p_cpo = empty_option; rettv->vval.v_number = -1; switch (type) { @@ -5007,9 +4987,9 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, li = TV_LIST_ITEM_NEXT(l, li); idx++; } else { - startcol = (colnr_T)(regmatch.startp[0] - + utfc_ptr2len((char *)regmatch.startp[0]) - str); - if (startcol > (colnr_T)len || str + startcol <= regmatch.startp[0]) { + startcol = (colnr_T)((char_u *)regmatch.startp[0] + + utfc_ptr2len(regmatch.startp[0]) - str); + if (startcol > (colnr_T)len || str + startcol <= (char_u *)regmatch.startp[0]) { match = false; break; } @@ -5028,8 +5008,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)((char_u *)regmatch.startp[0] - expr); + TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)(regmatch.endp[0] - (char *)expr); if (l != NULL) { TV_LIST_ITEM_TV(li2)->vval.v_number = (varnumber_T)idx; } @@ -5064,10 +5044,10 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, } else { if (type == kSomeMatch) { rettv->vval.v_number = - (varnumber_T)(regmatch.startp[0] - str); + (varnumber_T)((char_u *)regmatch.startp[0] - str); } else { rettv->vval.v_number = - (varnumber_T)(regmatch.endp[0] - str); + (varnumber_T)(regmatch.endp[0] - (char *)str); } rettv->vval.v_number += (varnumber_T)(str - expr); } @@ -5089,31 +5069,31 @@ theend: } /// "match()" function -static void f_match(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_match(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { find_some_match(argvars, rettv, kSomeMatch); } /// "matchend()" function -static void f_matchend(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_matchend(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { find_some_match(argvars, rettv, kSomeMatchEnd); } /// "matchlist()" function -static void f_matchlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_matchlist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { find_some_match(argvars, rettv, kSomeMatchList); } /// "matchstr()" function -static void f_matchstr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_matchstr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { find_some_match(argvars, rettv, kSomeMatchStr); } /// "matchstrpos()" function -static void f_matchstrpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_matchstrpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { find_some_match(argvars, rettv, kSomeMatchStrPos); } @@ -5168,19 +5148,19 @@ 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) +static void f_max(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { max_min(argvars, rettv, true); } /// "min()" function -static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_min(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { max_min(argvars, rettv, false); } /// "mkdir()" function -static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_mkdir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int prot = 0755; // -V536 @@ -5225,7 +5205,7 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "mode()" function -static void f_mode(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_mode(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char buf[MODE_MAX_LENGTH]; @@ -5242,7 +5222,7 @@ static void f_mode(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "msgpackdump()" function -static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_msgpackdump(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) FUNC_ATTR_NONNULL_ALL { if (argvars[0].v_type != VAR_LIST) { @@ -5381,7 +5361,7 @@ static void msgpackparse_unpack_blob(const blob_T *const blob, list_T *const ret } /// "msgpackparse" function -static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_msgpackparse(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) FUNC_ATTR_NONNULL_ALL { if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) { @@ -5397,7 +5377,7 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "nextnonblank()" function -static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_nextnonblank(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { linenr_T lnum; @@ -5406,7 +5386,7 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr) lnum = 0; break; } - if (*skipwhite((char *)ml_get(lnum)) != NUL) { + if (*skipwhite(ml_get(lnum)) != NUL) { break; } } @@ -5414,7 +5394,7 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "nr2char()" function -static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_nr2char(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[1].v_type != VAR_UNKNOWN) { if (!tv_check_num(&argvars[1])) { @@ -5445,14 +5425,14 @@ static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "or(expr, expr)" function -static void f_or(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_or(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL) | tv_get_number_chk(&argvars[1], NULL); } /// "pathshorten()" function -static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_pathshorten(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int trim_len = 1; @@ -5464,17 +5444,17 @@ static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr) } rettv->v_type = VAR_STRING; - const char_u *p = (char_u *)tv_get_string_chk(&argvars[0]); + const char *p = tv_get_string_chk(&argvars[0]); if (p == NULL) { rettv->vval.v_string = NULL; } else { - rettv->vval.v_string = (char *)vim_strsave(p); + rettv->vval.v_string = xstrdup(p); shorten_dir_len((char_u *)rettv->vval.v_string, trim_len); } } /// "pow()" function -static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_pow(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { float_T fx; float_T fy; @@ -5488,13 +5468,13 @@ static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "prevnonblank()" function -static void f_prevnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_prevnonblank(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { linenr_T lnum = tv_get_lnum(argvars); if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) { lnum = 0; } else { - while (lnum >= 1 && *skipwhite((char *)ml_get(lnum)) == NUL) { + while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) { lnum--; } } @@ -5502,7 +5482,7 @@ static void f_prevnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "printf()" function -static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_printf(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -5524,7 +5504,7 @@ 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) +static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { Callback prompt_callback = { .type = kCallbackNone }; @@ -5547,7 +5527,7 @@ 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) +static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { Callback interrupt_callback = { .type = kCallbackNone }; @@ -5570,7 +5550,7 @@ static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fpt } /// "prompt_getprompt({buffer})" function -static void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) FUNC_ATTR_NONNULL_ALL { // return an empty string by default, e.g. it's not a prompt buffer @@ -5586,11 +5566,11 @@ static void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - rettv->vval.v_string = (char *)vim_strsave(buf_prompt_text(buf)); + rettv->vval.v_string = xstrdup(buf_prompt_text(buf)); } /// "prompt_setprompt({buffer}, {text})" function -static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure()) { return; @@ -5606,14 +5586,14 @@ static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "pum_getpos()" function -static void f_pum_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_pum_getpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_alloc_ret(rettv); pum_set_event_info(rettv->vval.v_dict); } /// "pumvisible()" function -static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_pumvisible(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (pum_visible()) { rettv->vval.v_number = 1; @@ -5621,7 +5601,7 @@ static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "py3eval()" and "pyxeval()" functions (always python3) -static void f_py3eval(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_py3eval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { script_host_eval("python3", argvars, rettv); } @@ -5693,7 +5673,7 @@ static inline uint32_t shuffle_xoshiro128starstar(uint32_t *const x, uint32_t *c } /// "rand()" function -static void f_rand(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_rand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { uint32_t result; @@ -5704,7 +5684,7 @@ static void f_rand(typval_T *argvars, typval_T *rettv, FunPtr fptr) // When no argument is given use the global seed list. if (!initialized) { // Initialize the global seed list. - uint32_t x; + uint32_t x = 0; init_srand(&x); gx = splitmix32(&x); @@ -5763,7 +5743,7 @@ theend: } /// "srand()" function -static void f_srand(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_srand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { uint32_t x = 0; @@ -5785,19 +5765,19 @@ static void f_srand(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "perleval()" function -static void f_perleval(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_perleval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { script_host_eval("perl", argvars, rettv); } /// "rubyeval()" function -static void f_rubyeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_rubyeval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { script_host_eval("ruby", argvars, rettv); } /// "range()" function -static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_range(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { varnumber_T end; varnumber_T stride = 1; @@ -5867,7 +5847,7 @@ theend: } /// "readdir()" function -static void f_readdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_readdir(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenUnknown); @@ -5885,14 +5865,14 @@ static void f_readdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "readfile()" function -static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_readfile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { bool binary = false; bool blob = false; FILE *fd; - char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1 + char buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1 int io_size = sizeof(buf); - char_u *prev = NULL; // previously read bytes, if any + char *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; @@ -5912,7 +5892,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) // their own about CR-LF conversion. const char *const fname = tv_get_string(&argvars[0]); - if (os_isdir((const char_u *)fname)) { + if (os_isdir(fname)) { semsg(_(e_isadir2), fname); return; } @@ -5943,13 +5923,13 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) // - an incomplete line gets written // - a "binary" file gets an empty line at the end if it ends in a // newline. - char_u *p; // Position in buf. - char_u *start; // Start of current line. + char *p; // Position in buf. + char *start; // Start of current line. for (p = buf, start = buf; p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary)); p++) { if (*p == '\n' || readlen <= 0) { - char_u *s = NULL; + char *s = NULL; size_t len = (size_t)(p - start); // Finished a line. Remove CRs before NL. @@ -5966,7 +5946,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (prevlen == 0) { assert(len < INT_MAX); - s = vim_strnsave(start, len); + s = xstrnsave(start, len); } else { // Change "prev" buffer to be the right size. This way // the bytes are only copied once, and very long lines are @@ -5981,7 +5961,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_list_append_owned_tv(l, (typval_T) { .v_type = VAR_STRING, .v_lock = VAR_UNLOCKED, - .vval.v_string = (char *)s, + .vval.v_string = s, }); start = p + 1; // Step over newline. @@ -6001,18 +5981,18 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) *p = '\n'; // Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this // when finding the BF and check the previous two bytes. - } else if (*p == 0xbf && !binary) { + } else if ((uint8_t)(*p) == 0xbf && !binary) { // Find the two bytes before the 0xbf. If p is at buf, or buf + 1, // these may be in the "prev" string. - char_u back1 = p >= buf + 1 ? p[-1] + char back1 = p >= buf + 1 ? p[-1] : prevlen >= 1 ? prev[prevlen - 1] : NUL; - char_u back2 = p >= buf + 2 ? p[-2] + char back2 = p >= buf + 2 ? p[-2] : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1] : prevlen >= - 2 ? prev[prevlen - 2] : NUL; + 2 ? prev[prevlen - 2] : NUL; - if (back2 == 0xef && back1 == 0xbb) { - char_u *dest = p - 2; + if ((uint8_t)back2 == 0xef && (uint8_t)back1 == 0xbb) { + char *dest = p - 2; // Usually a BOM is at the beginning of a file, and so at // the beginning of a line; then we can just step over it. @@ -6068,7 +6048,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "getreginfo()" function -static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_getreginfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int regname = getreg_get_regname(argvars); if (regname == 0) { @@ -6118,18 +6098,18 @@ static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "reg_executing()" function -static void f_reg_executing(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reg_executing(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { return_register(reg_executing, rettv); } /// "reg_recording()" function -static void f_reg_recording(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reg_recording(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { return_register(reg_recording, rettv); } -static void f_reg_recorded(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reg_recorded(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { return_register(reg_recorded, rettv); } @@ -6171,7 +6151,7 @@ static int list2proftime(typval_T *arg, proftime_T *tm) FUNC_ATTR_NONNULL_ALL /// one argument it returns the time passed since the argument. /// With two arguments it returns the time passed between /// the two arguments. -static void f_reltime(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reltime(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { proftime_T res; proftime_T start; @@ -6213,7 +6193,7 @@ static void f_reltime(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "reltimestr()" function -static void f_reltimestr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reltimestr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) FUNC_ATTR_NONNULL_ALL { proftime_T tm; @@ -6226,7 +6206,7 @@ static void f_reltimestr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "remove()" function -static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_remove(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const arg_errmsg = N_("remove() argument"); @@ -6242,19 +6222,19 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "rename({from}, {to})" function -static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_rename(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure()) { rettv->vval.v_number = -1; } else { char buf[NUMBUFLEN]; - rettv->vval.v_number = vim_rename((const char_u *)tv_get_string(&argvars[0]), - (const char_u *)tv_get_string_buf(&argvars[1], buf)); + rettv->vval.v_number = vim_rename(tv_get_string(&argvars[0]), + tv_get_string_buf(&argvars[1], buf)); } } /// "repeat()" function -static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_repeat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { varnumber_T n = tv_get_number(&argvars[1]); if (argvars[0].v_type == VAR_LIST) { @@ -6291,7 +6271,7 @@ static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "resolve()" function -static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_resolve(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; const char *fname = tv_get_string(&argvars[0]); @@ -6302,7 +6282,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) v = os_realpath(fname, v); } } - rettv->vval.v_string = (char_u *)(v == NULL ? xstrdup(fname) : v); + rettv->vval.v_string = (v == NULL ? xstrdup(fname) : v); #else # ifdef HAVE_READLINK { @@ -6364,7 +6344,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (*q != NUL) { cpy = remain; remain = (remain - ? (char *)concat_str((char_u *)q - 1, (char_u *)remain) + ? concat_str(q - 1, remain) : xstrdup(q - 1)); xfree(cpy); q[-1] = NUL; @@ -6423,7 +6403,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) && (p[2] == NUL || vim_ispathsep(p[2])))))) { // Prepend "./". - cpy = (char *)concat_str((const char_u *)"./", (const char_u *)p); + cpy = concat_str("./", p); xfree(p); p = cpy; } else if (!is_relative_to_current) { @@ -6460,7 +6440,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "reverse({list})" function -static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reverse(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type == VAR_BLOB) { blob_T *const b = argvars[0].vval.v_blob; @@ -6485,7 +6465,7 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "reduce(list, { accumulator, element -> value } [, initial])" function -static void f_reduce(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reduce(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) { emsg(_(e_listblobreq)); @@ -6785,7 +6765,7 @@ theend: } /// "rpcnotify()" function -static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_rpcnotify(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -6820,7 +6800,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "rpcrequest()" function -static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -6909,12 +6889,12 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) } end: - arena_mem_free(res_mem, NULL); + arena_mem_free(res_mem); api_clear_error(&err); } /// "rpcstart()" function (DEPRECATED) -static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_rpcstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -6981,7 +6961,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "rpcstop()" function -static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_rpcstop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; @@ -6999,7 +6979,7 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) // if called with a job, stop it, else closes the channel uint64_t id = (uint64_t)argvars[0].vval.v_number; if (find_job(id, false)) { - f_jobstop(argvars, rettv, NULL); + f_jobstop(argvars, rettv, fptr); } else { const char *error; rettv->vval.v_number = @@ -7011,7 +6991,7 @@ 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) +static void f_screenattr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; @@ -7029,7 +7009,7 @@ 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) +static void f_screenchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; @@ -7047,7 +7027,7 @@ 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) +static void f_screenchars(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; @@ -7060,7 +7040,7 @@ static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } int pcc[MAX_MCO]; - int c = utfc_ptr2char(grid->chars[grid->line_offset[row] + (size_t)col], pcc); + int c = utfc_ptr2char((char *)grid->chars[grid->line_offset[row] + (size_t)col], pcc); int composing_len = 0; while (pcc[composing_len] != 0) { composing_len++; @@ -7075,45 +7055,19 @@ static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "screencol()" function /// /// First column is 1 to be consistent with virtcol(). -static void f_screencol(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_screencol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = ui_current_col() + 1; } -/// "screenpos({winid}, {lnum}, {col})" function -static void f_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - tv_dict_alloc_ret(rettv); - dict_T *dict = rettv->vval.v_dict; - - win_T *wp = find_win_by_nr_or_id(&argvars[0]); - if (wp == NULL) { - return; - } - - 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); - tv_dict_add_nr(dict, S_LEN("col"), scol); - tv_dict_add_nr(dict, S_LEN("curscol"), ccol); - tv_dict_add_nr(dict, S_LEN("endcol"), ecol); -} - /// "screenrow()" function -static void f_screenrow(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_screenrow(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = ui_current_row() + 1; } /// "screenstring()" function -static void f_screenstring(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_screenstring(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_string = NULL; rettv->v_type = VAR_STRING; @@ -7128,11 +7082,11 @@ static void f_screenstring(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - rettv->vval.v_string = (char *)vim_strsave(grid->chars[grid->line_offset[row] + (size_t)col]); + rettv->vval.v_string = xstrdup((char *)grid->chars[grid->line_offset[row] + (size_t)col]); } /// "search()" function -static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_search(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int flags = 0; @@ -7140,7 +7094,7 @@ static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "searchdecl()" function -static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_searchdecl(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int locally = 1; int thisblock = 0; @@ -7235,13 +7189,13 @@ theend: } /// "searchpair()" function -static void f_searchpair(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_searchpair(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = searchpair_cmn(argvars, NULL); } /// "searchpairpos()" function -static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_searchpairpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { pos_T match_pos; int lnum = 0; @@ -7283,7 +7237,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir // Make 'cpoptions' empty, the 'l' flag should not be used here. char *save_cpo = p_cpo; - p_cpo = (char *)empty_option; + p_cpo = empty_option; // Set the time limit, if there is one. proftime_T tm = profile_setlimit(time_limit); @@ -7409,18 +7363,23 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir xfree(pat2); xfree(pat3); - if ((char_u *)p_cpo == empty_option) { + if (p_cpo == empty_option) { p_cpo = save_cpo; } else { // Darn, evaluating the {skip} expression changed the value. - free_string_option((char_u *)save_cpo); + // If it's still empty it was changed and restored, need to restore in + // the complicated way. + if (*p_cpo == NUL) { + set_option_value_give_err("cpo", 0L, save_cpo, 0); + } + free_string_option(save_cpo); } return retval; } /// "searchpos()" function -static void f_searchpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_searchpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { pos_T match_pos; int flags = 0; @@ -7440,7 +7399,7 @@ static void f_searchpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "serverlist()" function -static void f_serverlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_serverlist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { size_t n; char **addrs = server_address_list(&n); @@ -7454,7 +7413,7 @@ static void f_serverlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "serverstart()" function -static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_serverstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; // Address of the new server @@ -7499,7 +7458,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "serverstop()" function -static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_serverstop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure()) { return; @@ -7519,7 +7478,7 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "setbufline()" function -static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { linenr_T lnum; buf_T *buf; @@ -7534,7 +7493,7 @@ static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// Set the cursor or mark position. -/// If 'charpos' is TRUE, then use the column number as a character offset. +/// If 'charpos' is true, then use the column number as a character offset. /// Otherwise use the column number as a byte offset. static void set_position(typval_T *argvars, typval_T *rettv, bool charpos) { @@ -7571,12 +7530,12 @@ static void set_position(typval_T *argvars, typval_T *rettv, bool charpos) } /// "setcharpos()" function -static void f_setcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setcharpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { set_position(argvars, rettv, true); } -static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setcharsearch(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); @@ -7588,7 +7547,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u *const csearch = (char_u *)tv_dict_get_string(d, "char", false); if (csearch != NULL) { int pcc[MAX_MCO]; - const int c = utfc_ptr2char(csearch, pcc); + const int c = utfc_ptr2char((char *)csearch, pcc); set_last_csearch(c, csearch, utfc_ptr2len((char *)csearch)); } @@ -7604,24 +7563,14 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/// "setcmdpos()" function -static void f_setcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) -{ - const int pos = (int)tv_get_number(&argvars[0]) - 1; - - if (pos >= 0) { - rettv->vval.v_number = set_cmdline_pos(pos); - } -} - /// "setcursorcharpos" function -static void f_setcursorcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setcursorcharpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { set_cursorpos(argvars, rettv, true); } /// "setenv()" function -static void f_setenv(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setenv(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char namebuf[NUMBUFLEN]; char valbuf[NUMBUFLEN]; @@ -7636,7 +7585,7 @@ static void f_setenv(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "setfperm({fname}, {mode})" function -static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setfperm(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = 0; @@ -7667,14 +7616,14 @@ static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "setline()" function -static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { linenr_T lnum = tv_get_lnum(&argvars[0]); set_buffer_lines(curbuf, lnum, false, &argvars[1], rettv); } /// "setpos()" function -static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { set_position(argvars, rettv, false); } @@ -7710,7 +7659,7 @@ static int get_yank_type(char **const pp, MotionType *const yank_type, long *con } /// "setreg()" function -static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_setreg(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { bool append = false; @@ -7836,7 +7785,7 @@ free_lstval: if (strval == NULL) { return; } - write_reg_contents_ex(regname, (const char_u *)strval, (ssize_t)STRLEN(strval), + write_reg_contents_ex(regname, strval, (ssize_t)STRLEN(strval), append, yank_type, (colnr_T)block_len); } if (pointreg != 0) { @@ -7851,7 +7800,7 @@ free_lstval: } /// "settagstack()" function -static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_settagstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { static char *e_invact2 = N_("E962: Invalid action: '%s'"); char action = 'r'; @@ -7902,7 +7851,7 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// f_sha256 - sha256({string}) function -static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_sha256(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *p = tv_get_string(&argvars[0]); const char *hash = sha256_bytes((const uint8_t *)p, strlen(p), NULL, 0); @@ -7913,7 +7862,7 @@ static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "shellescape({string})" function -static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_shellescape(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const bool do_special = non_zero_arg(&argvars[1]); @@ -7924,7 +7873,7 @@ static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// shiftwidth() function -static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_shiftwidth(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = 0; @@ -7940,7 +7889,7 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "simplify()" function -static void f_simplify(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_simplify(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const p = tv_get_string(&argvars[0]); rettv->vval.v_string = xstrdup(p); @@ -7949,7 +7898,7 @@ static void f_simplify(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "sockconnect()" function -static void f_sockconnect(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_sockconnect(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_STRING) { emsg(_(e_invarg)); @@ -8001,7 +7950,7 @@ static void f_sockconnect(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "stdioopen()" function -static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_stdioopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_DICT) { emsg(_(e_invarg)); @@ -8035,7 +7984,7 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "reltimefloat()" function -static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_reltimefloat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) FUNC_ATTR_NONNULL_ALL { proftime_T tm; @@ -8048,7 +7997,7 @@ static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "soundfold({word})" function -static void f_soundfold(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_soundfold(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; const char *const s = tv_get_string(&argvars[0]); @@ -8056,7 +8005,7 @@ 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) +static void f_spellbadword(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const int wo_spell_save = curwin->w_p_spell; @@ -8078,7 +8027,7 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Find the start and length of the badly spelled word. len = spell_move_to(curwin, FORWARD, true, true, &attr); if (len != 0) { - word = (char *)get_cursor_pos_ptr(); + word = get_cursor_pos_ptr(); curwin->w_set_curswant = true; } } else if (*curbuf->b_s.b_p_spl != NUL) { @@ -8112,7 +8061,7 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "spellsuggest()" function -static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_spellsuggest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { garray_T ga = GA_EMPTY_INIT_VALUE; const int wo_spell_save = curwin->w_p_spell; @@ -8159,7 +8108,7 @@ f_spellsuggest_return: curwin->w_p_spell = wo_spell_save; } -static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_split(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { colnr_T col = 0; bool keepempty = false; @@ -8167,7 +8116,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Make 'cpoptions' empty, the 'l' flag should not be used here. char *save_cpo = p_cpo; - p_cpo = ""; + p_cpo = empty_option; const char *str = tv_get_string(&argvars[0]); const char *pat = NULL; @@ -8221,11 +8170,11 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) break; } // Advance to just after the match. - if (regmatch.endp[0] > (char_u *)str) { + if (regmatch.endp[0] > str) { col = 0; } else { // Don't get stuck at the same match. - col = utfc_ptr2len((char *)regmatch.endp[0]); + col = utfc_ptr2len(regmatch.endp[0]); } str = (const char *)regmatch.endp[0]; } @@ -8238,7 +8187,7 @@ theend: } /// "stdpath(type)" function -static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_stdpath(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -8270,7 +8219,7 @@ static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "str2float()" function -static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_str2float(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char *p = skipwhite(tv_get_string(&argvars[0])); bool isneg = (*p == '-'); @@ -8286,7 +8235,7 @@ static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "str2list()" function -static void f_str2list(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_str2list(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenUnknown); const char_u *p = (const char_u *)tv_get_string(&argvars[0]); @@ -8297,7 +8246,7 @@ static void f_str2list(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "str2nr()" function -static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_str2nr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int base = 10; int what = 0; @@ -8330,7 +8279,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) break; } varnumber_T n; - vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, false); + vim_str2nr((char *)p, NULL, NULL, what, &n, NULL, 0, false); // Text after the number is silently ignored. if (isneg) { rettv->vval.v_number = -n; @@ -8340,7 +8289,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strftime({format}[, {time}])" function -static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strftime(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { time_t seconds; @@ -8360,13 +8309,12 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_string = xstrdup(_("(Invalid)")); } else { vimconv_T conv; - char_u *enc; conv.vc_type = CONV_NONE; - enc = enc_locale(); + char *enc = (char *)enc_locale(); convert_setup(&conv, p_enc, enc); if (conv.vc_type != CONV_NONE) { - p = (char *)string_convert(&conv, (char_u *)p, NULL); + p = string_convert(&conv, p, NULL); } char result_buf[256]; if (p != NULL) { @@ -8380,7 +8328,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) } convert_setup(&conv, enc, p_enc); if (conv.vc_type != CONV_NONE) { - rettv->vval.v_string = (char *)string_convert(&conv, (char_u *)result_buf, NULL); + rettv->vval.v_string = string_convert(&conv, result_buf, NULL); } else { rettv->vval.v_string = xstrdup(result_buf); } @@ -8392,7 +8340,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strgetchar()" function -static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strgetchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = -1; @@ -8420,7 +8368,7 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "stridx()" function -static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_stridx(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = -1; @@ -8452,20 +8400,20 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "string()" function -static void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_string(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = encode_tv2string(&argvars[0], NULL); } /// "strlen()" function -static void f_strlen(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strlen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0])); } /// "strchars()" function -static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strchars(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *s = tv_get_string(&argvars[0]); int skipcc = 0; @@ -8488,7 +8436,7 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strdisplaywidth()" function -static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const s = tv_get_string(&argvars[0]); int col = 0; @@ -8497,11 +8445,11 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) col = (int)tv_get_number(&argvars[1]); } - rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char_u *)s) - col); + rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char *)s) - col); } /// "strwidth()" function -static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strwidth(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const s = tv_get_string(&argvars[0]); @@ -8509,7 +8457,7 @@ static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strcharpart()" function -static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strcharpart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const p = tv_get_string(&argvars[0]); const size_t slen = STRLEN(p); @@ -8563,7 +8511,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strpart()" function -static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strpart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { bool error = false; @@ -8609,7 +8557,7 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strptime({format}, {timestring})" function -static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strptime(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char fmt_buf[NUMBUFLEN]; char str_buf[NUMBUFLEN]; @@ -8623,10 +8571,10 @@ static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr) vimconv_T conv = { .vc_type = CONV_NONE, }; - char_u *enc = enc_locale(); + char *enc = (char *)enc_locale(); convert_setup(&conv, p_enc, enc); if (conv.vc_type != CONV_NONE) { - fmt = (char *)string_convert(&conv, (char_u *)fmt, NULL); + fmt = string_convert(&conv, fmt, NULL); } if (fmt == NULL || os_strptime(str, fmt, &tmval) == NULL @@ -8641,7 +8589,7 @@ static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strridx()" function -static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strridx(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char buf[NUMBUFLEN]; const char *const needle = tv_get_string_chk(&argvars[1]); @@ -8684,14 +8632,14 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "strtrans()" function -static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_strtrans(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = transstr(tv_get_string(&argvars[0]), true); } /// "submatch()" function -static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_submatch(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { bool error = false; int no = (int)tv_get_number_chk(&argvars[0], &error); @@ -8714,7 +8662,7 @@ static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (retList == 0) { rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)reg_submatch(no); + rettv->vval.v_string = reg_submatch(no); } else { rettv->v_type = VAR_LIST; rettv->vval.v_list = reg_submatch_list(no); @@ -8722,7 +8670,7 @@ static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "substitute()" function -static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_substitute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char patbuf[NUMBUFLEN]; char subbuf[NUMBUFLEN]; @@ -8751,14 +8699,14 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "swapinfo(swap_filename)" function -static void f_swapinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_swapinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_alloc_ret(rettv); get_b0_dict(tv_get_string(argvars), rettv->vval.v_dict); } /// "swapname(expr)" function -static void f_swapname(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_swapname(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; buf_T *buf = tv_get_buf(&argvars[0], false); @@ -8767,12 +8715,12 @@ static void f_swapname(typval_T *argvars, typval_T *rettv, FunPtr fptr) || buf->b_ml.ml_mfp->mf_fname == NULL) { rettv->vval.v_string = NULL; } else { - rettv->vval.v_string = (char *)vim_strsave(buf->b_ml.ml_mfp->mf_fname); + rettv->vval.v_string = xstrdup(buf->b_ml.ml_mfp->mf_fname); } } /// "synID(lnum, col, trans)" function -static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_synID(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { // -1 on type error (both) const linenr_T lnum = tv_get_lnum(argvars); @@ -8791,7 +8739,7 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "synIDattr(id, what [, mode])" function -static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_synIDattr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const int id = (int)tv_get_number(&argvars[0]); const char *const what = tv_get_string(&argvars[1]); @@ -8878,7 +8826,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "synIDtrans(id)" function -static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_synIDtrans(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int id = (int)tv_get_number(&argvars[0]); @@ -8892,7 +8840,7 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "synconcealed(lnum, col)" function -static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_synconcealed(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int syntax_flags = 0; int cchar; @@ -8934,7 +8882,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "synstack(lnum, col)" function -static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_synstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_set_ret(rettv, NULL); @@ -8958,18 +8906,18 @@ static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// f_system - the VimL system() function -static void f_system(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_system(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { get_system_output_as_rettv(argvars, rettv, false); } -static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_systemlist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { get_system_output_as_rettv(argvars, rettv, true); } /// "tabpagebuflist()" function -static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp = NULL; @@ -8991,7 +8939,7 @@ static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "tabpagenr()" function -static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_tabpagenr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int nr = 1; @@ -9077,7 +9025,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar) } /// "tabpagewinnr()" function -static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int nr = 1; tabpage_T *const tp = find_tabpage((int)tv_get_number(&argvars[0])); @@ -9090,14 +9038,14 @@ 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) +static void f_tagfiles(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenUnknown); char *fname = xmalloc(MAXPATHL); bool first = true; tagname_T tn; - while (get_tagfname(&tn, first, (char_u *)fname) == OK) { + while (get_tagfname(&tn, first, fname) == OK) { tv_list_append_string(rettv->vval.v_list, fname, -1); first = false; } @@ -9107,7 +9055,7 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "taglist()" function -static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_taglist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const tag_pattern = tv_get_string(&argvars[0]); @@ -9125,14 +9073,14 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "tempname()" function -static void f_tempname(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_tempname(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)vim_tempname(); + rettv->vval.v_string = vim_tempname(); } /// "termopen(cmd[, cwd])" function -static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure()) { return; @@ -9175,7 +9123,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((const char_u *)cwd)) { + if (!os_isdir(cwd)) { semsg(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; @@ -9255,7 +9203,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "timer_info([timer])" function -static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_timer_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_UNKNOWN) { if (argvars[0].v_type != VAR_NUMBER) { @@ -9273,7 +9221,7 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "timer_pause(timer, paused)" function -static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr) +static void f_timer_pause(typval_T *argvars, typval_T *unused, EvalFuncData fptr) { if (argvars[0].v_type != VAR_NUMBER) { emsg(_(e_number_exp)); @@ -9293,7 +9241,7 @@ static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr) } /// "timer_start(timeout, callback, opts)" function -static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_timer_start(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int repeat = 1; @@ -9325,7 +9273,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "timer_stop(timerid)" function -static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_timer_stop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_NUMBER) { emsg(_(e_number_exp)); @@ -9340,27 +9288,27 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr) timer_stop(timer); } -static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr) +static void f_timer_stopall(typval_T *argvars, typval_T *unused, EvalFuncData fptr) { timer_stop_all(); } /// "tolower(string)" function -static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_tolower(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = strcase_save(tv_get_string(&argvars[0]), false); } /// "toupper(string)" function -static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_toupper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = strcase_save(tv_get_string(&argvars[0]), true); } /// "tr(string, fromstr, tostr)" function -static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_tr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char buf[NUMBUFLEN]; char buf2[NUMBUFLEN]; @@ -9439,14 +9387,14 @@ error: } /// "trim({expr})" function -static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_trim(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char buf1[NUMBUFLEN]; 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 *prev; - const char_u *p; + const char *head = tv_get_string_buf_chk(&argvars[0], buf1); + const char *mask = NULL; + const char *prev; + const char *p; int dir = 0; rettv->v_type = VAR_STRING; @@ -9455,8 +9403,13 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_STRING) { + semsg(_(e_invarg2), tv_get_string(&argvars[1])); + return; + } + if (argvars[1].v_type == VAR_STRING) { - mask = (const char_u *)tv_get_string_buf_chk(&argvars[1], buf2); + mask = tv_get_string_buf_chk(&argvars[1], buf2); if (argvars[2].v_type != VAR_UNKNOWN) { bool error = false; // leading or trailing characters to trim @@ -9494,7 +9447,7 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - const char_u *tail = head + STRLEN(head); + const char *tail = head + STRLEN(head); if (dir == 0 || dir == 2) { // Trim trailing characters for (; tail > head; tail = prev) { @@ -9517,11 +9470,11 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } - rettv->vval.v_string = (char *)vim_strnsave(head, (size_t)(tail - head)); + rettv->vval.v_string = xstrnsave(head, (size_t)(tail - head)); } /// "type(expr)" function -static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_type(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int n = -1; @@ -9553,7 +9506,7 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "undofile(name)" function -static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_undofile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; const char *const fname = tv_get_string(&argvars[0]); @@ -9572,7 +9525,7 @@ static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "undotree()" function -static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_undotree(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_alloc_ret(rettv); @@ -9590,7 +9543,7 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "virtcol(string)" function -static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_virtcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { colnr_T vcol = 0; int fnum = curbuf->b_fnum; @@ -9615,14 +9568,14 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "visualmode()" function -static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_visualmode(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - char_u str[2]; + char str[2]; rettv->v_type = VAR_STRING; - str[0] = (char_u)curbuf->b_visual_mode_eval; + str[0] = (char)curbuf->b_visual_mode_eval; str[1] = NUL; - rettv->vval.v_string = (char *)vim_strsave(str); + rettv->vval.v_string = xstrdup(str); // A non-zero number or non-empty string argument: reset mode. if (non_zero_arg(&argvars[0])) { @@ -9631,7 +9584,7 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "wildmenumode()" function -static void f_wildmenumode(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_wildmenumode(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (wild_menu_showing || ((State & MODE_CMDLINE) && cmdline_pum_active())) { rettv->vval.v_number = 1; @@ -9639,20 +9592,20 @@ static void f_wildmenumode(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "win_findbuf()" function -static void f_win_findbuf(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_findbuf(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenMayKnow); win_findbuf(argvars, rettv->vval.v_list); } /// "win_getid()" function -static void f_win_getid(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_getid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = win_getid(argvars); } /// "win_gettype(nr)" function -static void f_win_gettype(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_gettype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp = curwin; @@ -9661,7 +9614,7 @@ static void f_win_gettype(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type != VAR_UNKNOWN) { wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) { - rettv->vval.v_string = (char *)vim_strsave((char_u *)"unknown"); + rettv->vval.v_string = xstrdup("unknown"); return; } } @@ -9679,25 +9632,37 @@ static void f_win_gettype(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "win_gotoid()" function -static void f_win_gotoid(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_gotoid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - rettv->vval.v_number = win_gotoid(argvars); + int id = (int)tv_get_number(&argvars[0]); + + if (cmdwin_type != 0) { + emsg(_(e_cmdwin)); + return; + } + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (wp->handle == id) { + goto_tabpage_win(tp, wp); + rettv->vval.v_number = 1; + return; + } + } } /// "win_id2tabwin()" function -static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_id2tabwin(argvars, rettv); } /// "win_id2win()" function -static void f_win_id2win(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_id2win(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = win_id2win(argvars); } /// "win_move_separator()" function -static void f_win_move_separator(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_move_separator(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = false; @@ -9712,7 +9677,7 @@ static void f_win_move_separator(typval_T *argvars, typval_T *rettv, FunPtr fptr } /// "win_move_statusline()" function -static void f_win_move_statusline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_win_move_statusline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp; int offset; @@ -9730,7 +9695,7 @@ static void f_win_move_statusline(typval_T *argvars, typval_T *rettv, FunPtr fpt } /// "winbufnr(nr)" function -static void f_winbufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_winbufnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) { @@ -9741,25 +9706,25 @@ static void f_winbufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "wincol()" function -static void f_wincol(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_wincol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { validate_cursor(); rettv->vval.v_number = curwin->w_wcol + 1; } /// "winheight(nr)" function -static void f_winheight(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_winheight(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) { rettv->vval.v_number = -1; } else { - rettv->vval.v_number = wp->w_height; + rettv->vval.v_number = wp->w_height_inner; } } /// "winlayout()" function -static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_winlayout(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tabpage_T *tp; @@ -9778,20 +9743,20 @@ static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "winline()" function -static void f_winline(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_winline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { validate_cursor(); rettv->vval.v_number = curwin->w_wrow + 1; } /// "winnr()" function -static void f_winnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_winnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = get_winnr(curtab, &argvars[0]); } /// "winrestcmd()" function -static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_winrestcmd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { char_u buf[50]; @@ -9818,7 +9783,7 @@ 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) +static void f_winrestview(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { dict_T *dict = argvars[0].vval.v_dict; @@ -9868,7 +9833,7 @@ 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) +static void f_winsaveview(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_alloc_ret(rettv); dict_T *dict = rettv->vval.v_dict; @@ -9886,32 +9851,32 @@ static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "winwidth(nr)" function -static void f_winwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_winwidth(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { win_T *wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) { rettv->vval.v_number = -1; } else { - rettv->vval.v_number = wp->w_width; + rettv->vval.v_number = wp->w_width_inner; } } /// "windowsversion()" function -static void f_windowsversion(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_windowsversion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; rettv->vval.v_string = xstrdup(windowsVersion); } /// "wordcount()" function -static void f_wordcount(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_wordcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_alloc_ret(rettv); cursor_pos_info(rettv->vval.v_dict); } /// "writefile()" function -static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_writefile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = -1; @@ -9989,7 +9954,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "xor(expr, expr)" function -static void f_xor(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static void f_xor(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL) ^ tv_get_number_chk(&argvars[1], NULL); diff --git a/src/nvim/eval/funcs.h b/src/nvim/eval/funcs.h index 583ee0e75e..adff0b2441 100644 --- a/src/nvim/eval/funcs.h +++ b/src/nvim/eval/funcs.h @@ -1,11 +1,12 @@ #ifndef NVIM_EVAL_FUNCS_H #define NVIM_EVAL_FUNCS_H +#include "nvim/api/private/dispatch.h" #include "nvim/buffer_defs.h" #include "nvim/eval/typval.h" /// Prototype of C function that implements VimL function -typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, FunPtr data); +typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, EvalFuncData data); /// Special flags for base_arg @see EvalFuncDef #define BASE_NONE 0 ///< Not a method (no base argument). @@ -13,13 +14,13 @@ typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, FunPtr data); /// Structure holding VimL function definition typedef struct { - char *name; ///< Name of the function. - uint8_t min_argc; ///< Minimal number of arguments. - uint8_t max_argc; ///< Maximal number of arguments. - uint8_t base_arg; ///< Method base arg # (1-indexed), BASE_NONE or BASE_LAST. - bool fast; ///< Can be run in |api-fast| events - VimLFunc func; ///< Function implementation. - FunPtr data; ///< Userdata for function implementation. + char *name; ///< Name of the function. + uint8_t min_argc; ///< Minimal number of arguments. + uint8_t max_argc; ///< Maximal number of arguments. + uint8_t base_arg; ///< Method base arg # (1-indexed), BASE_NONE or BASE_LAST. + bool fast; ///< Can be run in |api-fast| events + VimLFunc func; ///< Function implementation. + EvalFuncData data; ///< Userdata for function implementation. } EvalFuncDef; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 8822bb0491..777cdc3013 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -40,6 +40,13 @@ # include "eval/typval.c.generated.h" #endif +static char e_string_required_for_argument_nr[] + = N_("E1174: String required for argument %d"); +static char e_non_empty_string_required_for_argument_nr[] + = N_("E1142: Non-empty string required for argument %d"); +static char e_number_required_for_argument_nr[] + = N_("E1210: Number required for argument %d"); + bool tv_in_free_unref_items = false; // TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead @@ -831,7 +838,7 @@ int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep) } /// "join()" function -void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_join(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_LIST) { emsg(_(e_listreq)); @@ -855,7 +862,7 @@ void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "list2str()" function -void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_list2str(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { garray_T ga; @@ -1016,7 +1023,7 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero) if (sortinfo->item_compare_lc) { res = strcoll(p1, p2); } else { - res = sortinfo->item_compare_ic ? STRICMP(p1, p2): STRCMP(p1, p2); + res = sortinfo->item_compare_ic ? STRICMP(p1, p2): strcmp(p1, p2); } } else { double n1, n2; @@ -1247,15 +1254,15 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) ; li != NULL;) { listitem_T *const prev_li = TV_LIST_ITEM_PREV(l, li); if (item_compare_func_ptr(&prev_li, &li) == 0) { - if (info.item_compare_func_err) { // -V547 - emsg(_("E882: Uniq compare function failed")); - break; - } li = tv_list_item_remove(l, li); } else { idx++; li = TV_LIST_ITEM_NEXT(l, li); } + if (info.item_compare_func_err) { // -V547 + emsg(_("E882: Uniq compare function failed")); + break; + } } } @@ -1267,13 +1274,13 @@ theend: } /// "sort"({list})" function -void f_sort(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_sort(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { do_sort_uniq(argvars, rettv, true); } /// "uniq({list})" function -void f_uniq(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_uniq(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { do_sort_uniq(argvars, rettv, false); } @@ -1568,7 +1575,7 @@ bool tv_callback_equal(const Callback *cb1, const Callback *cb2) } switch (cb1->type) { case kCallbackFuncref: - return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0; + return strcmp(cb1->data.funcref, cb2->data.funcref) == 0; case kCallbackPartial: // FIXME: this is inconsistent with tv_equal but is needed for precision // maybe change dictwatcheradd to return a watcher id instead? @@ -2533,7 +2540,7 @@ dict_T *tv_dict_copy(const vimconv_T *const conv, dict_T *const orig, const bool new_di = tv_dict_item_alloc((const char *)di->di_key); } else { size_t len = STRLEN(di->di_key); - char *const key = (char *)string_convert(conv, di->di_key, &len); + char *const key = (char *)string_convert(conv, (char *)di->di_key, &len); if (key == NULL) { new_di = tv_dict_item_alloc_len((const char *)di->di_key, len); } else { @@ -2777,7 +2784,7 @@ static void tv_dict_list(typval_T *const tv, typval_T *const rettv, const DictLi switch (what) { case kDictListKeys: tv_item.v_type = VAR_STRING; - tv_item.vval.v_string = (char *)vim_strsave(di->di_key); + tv_item.vval.v_string = xstrdup((char *)di->di_key); break; case kDictListValues: tv_copy(&di->di_tv, &tv_item); @@ -2806,25 +2813,25 @@ static void tv_dict_list(typval_T *const tv, typval_T *const rettv, const DictLi } /// "items(dict)" function -void f_items(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_items(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_list(argvars, rettv, 2); } /// "keys()" function -void f_keys(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_keys(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_list(argvars, rettv, 0); } /// "values(dict)" function -void f_values(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_values(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_dict_list(argvars, rettv, 1); } /// "has_key()" function -void f_has_key(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_has_key(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); @@ -3717,8 +3724,7 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error) case VAR_STRING: { varnumber_T n = 0; if (tv->vval.v_string != NULL) { - vim_str2nr((char_u *)tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0, - false); + vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0, false); } return n; } @@ -3801,31 +3807,50 @@ float_T tv_get_float(const typval_T *const tv) return 0; } -// Give an error and return FAIL unless "tv" is a string. -int tv_check_for_string(const typval_T *const tv) +/// Give an error and return FAIL unless "args[idx]" is a string. +int tv_check_for_string_arg(const typval_T *const args, const int idx) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { - if (tv->v_type != VAR_STRING) { - emsg(_(e_stringreq)); + if (args[idx].v_type != VAR_STRING) { + semsg(_(e_string_required_for_argument_nr), idx + 1); return FAIL; } return OK; } -// Give an error and return FAIL unless "tv" is a non-empty string. -int tv_check_for_nonempty_string(const typval_T *const tv) +/// Give an error and return FAIL unless "args[idx]" is a non-empty string. +int tv_check_for_nonempty_string_arg(const typval_T *const args, const int idx) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { - if (tv_check_for_string(tv) == FAIL) { + if (tv_check_for_string_arg(args, idx) == FAIL) { return FAIL; } - if (tv->vval.v_string == NULL || *tv->vval.v_string == NUL) { - emsg(_(e_non_empty_string_required)); + if (args[idx].vval.v_string == NULL || *args[idx].vval.v_string == NUL) { + semsg(_(e_non_empty_string_required_for_argument_nr), idx + 1); return FAIL; } return OK; } +/// Give an error and return FAIL unless "args[idx]" is a number. +int tv_check_for_number_arg(const typval_T *const args, const int idx) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE +{ + if (args[idx].v_type != VAR_NUMBER) { + semsg(_(e_number_required_for_argument_nr), idx + 1); + return FAIL; + } + return OK; +} + +/// Check for an optional number argument at "idx" +int tv_check_for_opt_number_arg(const typval_T *const args, const int idx) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE +{ + return (args[idx].v_type == VAR_UNKNOWN + || tv_check_for_number_arg(args, idx) != FAIL) ? OK : FAIL; +} + /// Get the string value of a "stringish" VimL object. /// /// @param[in] tv Object to get value of. diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index c4bc9f603b..6373ead1a3 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -25,9 +25,6 @@ typedef int64_t varnumber_T; typedef uint64_t uvarnumber_T; -/// Type used for VimL VAR_FLOAT values -typedef double float_T; - /// Refcount for dict or list that should not be freed enum { DO_NOT_FREE_CNT = (INT_MAX / 2), }; @@ -289,12 +286,6 @@ typedef struct { /// Number of fixed variables used for arguments #define FIXVAR_CNT 12 -/// Callback interface for C function reference> -/// Used for managing functions that were registered with |register_cfunc| -typedef int (*cfunc_T)(int argcount, typval_T *argvars, typval_T *rettv, void *state); // NOLINT -/// Callback to clear cfunc_T and any associated state. -typedef void (*cfunc_free_T)(void *state); - // Structure to hold info for a function that is currently being executed. typedef struct funccall_S funccall_T; @@ -333,10 +324,7 @@ struct ufunc { garray_T uf_lines; ///< function lines int uf_profiling; ///< true when func is being profiled int uf_prof_initialized; - // Managing cfuncs - cfunc_T uf_cb; ///< C function extension callback - cfunc_free_T uf_cb_free; ///< C function extension free callback - void *uf_cb_state; ///< State of C function extension. + LuaRef uf_luaref; ///< lua callback, used if (uf_flags & FC_LUAREF) // Profiling the function as a whole. int uf_tm_count; ///< nr of calls proftime_T uf_tm_total; ///< time spent in function + children @@ -363,15 +351,14 @@ struct ufunc { }; struct partial_S { - int pt_refcount; ///< Reference count. - char_u *pt_name; ///< Function name; when NULL use pt_func->name. - ufunc_T *pt_func; ///< Function pointer; when NULL lookup function with - ///< pt_name. - bool pt_auto; ///< When true the partial was created by using dict.member - ///< in handle_subscript(). - int pt_argc; ///< Number of arguments. + int pt_refcount; ///< Reference count. + char *pt_name; ///< Function name; when NULL use pt_func->name. + ufunc_T *pt_func; ///< Function pointer; when NULL lookup function with pt_name. + bool pt_auto; ///< When true the partial was created by using dict.member + ///< in handle_subscript(). + int pt_argc; ///< Number of arguments. typval_T *pt_argv; ///< Arguments in allocated array. - dict_T *pt_dict; ///< Dict for "self". + dict_T *pt_dict; ///< Dict for "self". }; /// Structure used for explicit stack while garbage collecting hash tables diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 7f64b39cd8..82709b044b 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -28,20 +28,6 @@ #include "nvim/ui.h" #include "nvim/vim.h" -// flags used in uf_flags -#define FC_ABORT 0x01 // abort function on error -#define FC_RANGE 0x02 // function accepts range -#define FC_DICT 0x04 // Dict function, uses "self" -#define FC_CLOSURE 0x08 // closure, uses outer scope variables -#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0 -#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0 -#define FC_SANDBOX 0x40 // function defined in the sandbox -#define FC_DEAD 0x80 // function kept only for reference to dfunc -#define FC_EXPORT 0x100 // "export def Func()" -#define FC_NOARGS 0x200 // no a: variables in lambda -#define FC_VIM9 0x400 // defined in vim9 script file -#define FC_CFUNC 0x800 // C function extension - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/userfunc.c.generated.h" #endif @@ -125,7 +111,7 @@ static int get_function_args(char **argp, char_u endchar, garray_T *newargs, int // Check for duplicate argument name. for (i = 0; i < newargs->ga_len; i++) { - if (STRCMP(((char **)(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; @@ -142,18 +128,18 @@ static int get_function_args(char **argp, char_u endchar, garray_T *newargs, int any_default = true; p = skipwhite(p) + 1; p = skipwhite(p); - char_u *expr = (char_u *)p; + char *expr = p; if (eval1(&p, &rettv, false) != FAIL) { ga_grow(default_args, 1); // trim trailing whitespace - while (p > (char *)expr && ascii_iswhite(p[-1])) { + while (p > expr && ascii_iswhite(p[-1])) { p--; } c = (char_u)(*p); *p = NUL; - expr = vim_strsave(expr); - ((char **)(default_args->ga_data))[default_args->ga_len] = (char *)expr; + expr = xstrdup(expr); + ((char **)(default_args->ga_data))[default_args->ga_len] = expr; default_args->ga_len++; *p = (char)c; } else { @@ -378,7 +364,7 @@ char_u *deref_func_name(const char *name, int *lenp, partial_T **const partialp, *lenp = 0; return (char_u *)""; } - *lenp = (int)STRLEN(v->di_tv.vval.v_string); + *lenp = (int)strlen(v->di_tv.vval.v_string); return (char_u *)v->di_tv.vval.v_string; } @@ -409,7 +395,7 @@ void emsg_funcname(char *ermsg, const char_u *name) char_u *p; if (*name == K_SPECIAL) { - p = concat_str((char_u *)"<SNR>", name + 3); + p = (char_u *)concat_str("<SNR>", (char *)name + 3); } else { p = (char_u *)name; } @@ -525,22 +511,22 @@ static inline bool eval_fname_sid(const char *const name) /// /// @return transformed name: either `fname_buf` or a pointer to an allocated /// memory. -static char_u *fname_trans_sid(const char_u *const name, char_u *const fname_buf, - char_u **const tofree, int *const error) +static char *fname_trans_sid(const char *const name, char *const fname_buf, char **const tofree, + int *const error) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - char_u *fname; - const int llen = eval_fname_script((const char *)name); + char *fname; + const int llen = eval_fname_script(name); if (llen > 0) { - fname_buf[0] = K_SPECIAL; - fname_buf[1] = KS_EXTRA; + fname_buf[0] = (char)K_SPECIAL; + fname_buf[1] = (char)KS_EXTRA; fname_buf[2] = KE_SNR; int i = 3; - if (eval_fname_sid((const char *)name)) { // "<SID>" or "s:" + if (eval_fname_sid(name)) { // "<SID>" or "s:" if (current_sctx.sc_sid <= 0) { *error = ERROR_SCRIPT; } else { - snprintf((char *)fname_buf + i, (size_t)(FLEN_FIXED + 1 - i), "%" PRId64 "_", + snprintf(fname_buf + i, (size_t)(FLEN_FIXED + 1 - i), "%" PRId64 "_", (int64_t)current_sctx.sc_sid); i = (int)STRLEN(fname_buf); } @@ -555,7 +541,7 @@ static char_u *fname_trans_sid(const char_u *const name, char_u *const fname_buf STRCPY(fname + i, name + llen); } } else { - fname = (char_u *)name; + fname = (char *)name; } return fname; @@ -758,9 +744,9 @@ static void func_clear_items(ufunc_T *fp) 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); - fp->uf_cb_free = NULL; + if (fp->uf_flags & FC_LUAREF) { + api_free_luaref(fp->uf_luaref); + fp->uf_luaref = LUA_NOREF; } XFREE_CLEAR(fp->uf_tml_count); @@ -856,7 +842,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett saveRedobuff(&save_redo); did_save_redo = true; } - ++fp->uf_calls; + fp->uf_calls++; // check for CTRL-C hit line_breakcheck(); // prepare the funccall_T structure @@ -867,7 +853,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett fc->rettv = rettv; fc->level = ex_nesting_level; // Check if this function has a breakpoint. - fc->breakpoint = dbg_find_breakpoint(false, fp->uf_name, (linenr_T)0); + fc->breakpoint = dbg_find_breakpoint(false, (char *)fp->uf_name, (linenr_T)0); fc->dbg_tick = debug_tick; // Set up fields for closure. @@ -897,7 +883,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett v->di_tv.v_type = VAR_DICT; v->di_tv.v_lock = VAR_UNLOCKED; v->di_tv.vval.v_dict = selfdict; - ++selfdict->dv_refcount; + selfdict->dv_refcount++; } // Init a: variables, unless none found (in lambda). @@ -974,11 +960,11 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett snprintf((char *)numbuf, sizeof(numbuf), "%d", ai + 1); name = (char *)numbuf; } - if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) { + if (fixvar_idx < FIXVAR_CNT && strlen(name) <= VAR_SHORT_LEN) { v = (dictitem_T *)&fc->fixvar[fixvar_idx++]; v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; } else { - v = xmalloc(sizeof(dictitem_T) + STRLEN(name)); + v = xmalloc(sizeof(dictitem_T) + strlen(name)); v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC; } STRCPY(v->di_key, name); @@ -1062,7 +1048,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett bool func_not_yet_profiling_but_should = do_profiling_yes - && !fp->uf_profiling && has_profiling(false, fp->uf_name, NULL); + && !fp->uf_profiling && has_profiling(false, (char *)fp->uf_name, NULL); if (func_not_yet_profiling_but_should) { started_profiling = true; @@ -1075,7 +1061,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett || (fc->caller != NULL && fc->caller->func->uf_profiling)); if (func_or_func_caller_profiling) { - ++fp->uf_tm_count; + fp->uf_tm_count++; call_start = profile_start(); fp->uf_tm_children = profile_zero(); } @@ -1087,7 +1073,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett const sctx_T save_current_sctx = current_sctx; current_sctx = fp->uf_script_ctx; save_did_emsg = did_emsg; - did_emsg = FALSE; + did_emsg = false; if (default_arg_err && (fp->uf_flags & FC_ABORT)) { did_emsg = true; @@ -1443,10 +1429,10 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t int ret = FAIL; int error = ERROR_NONE; ufunc_T *fp = NULL; - char_u fname_buf[FLEN_FIXED + 1]; - char_u *tofree = NULL; - char_u *fname = NULL; - char_u *name = NULL; + char fname_buf[FLEN_FIXED + 1]; + char *tofree = NULL; + char *fname = NULL; + char *name = NULL; int argcount = argcount_in; typval_T *argvars = argvars_in; dict_T *selfdict = funcexe->selfdict; @@ -1461,7 +1447,7 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t rettv->v_type = VAR_UNKNOWN; if (len <= 0) { - len = (int)STRLEN(funcname); + len = (int)strlen(funcname); } if (partial != NULL) { fp = partial->pt_func; @@ -1469,8 +1455,8 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t if (fp == NULL) { // Make a copy of the name, if it comes from a funcref variable it could // be changed or deleted in the called function. - name = vim_strnsave((char_u *)funcname, (size_t)len); - fname = fname_trans_sid(name, fname_buf, &tofree, &error); + name = xstrnsave(funcname, (size_t)len); + fname = fname_trans_sid(name, (char *)fname_buf, &tofree, &error); } if (funcexe->doesrange != NULL) { @@ -1501,7 +1487,7 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t } if (error == ERROR_NONE && funcexe->evaluate) { - char_u *rfname = fname; + char *rfname = fname; // Ignore "g:" before a function name. if (fp == NULL && fname[0] == 'g' && fname[1] == ':') { @@ -1525,28 +1511,27 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t } else if (fp != NULL || !builtin_function((const char *)rfname, -1)) { // User defined function. if (fp == NULL) { - fp = find_func(rfname); + fp = find_func((char_u *)rfname); } // Trigger FuncUndefined event, may load the function. if (fp == NULL - && apply_autocmds(EVENT_FUNCUNDEFINED, (char *)rfname, (char *)rfname, true, NULL) + && apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, true, NULL) && !aborting()) { // executed an autocommand, search for the function again - fp = find_func(rfname); + fp = find_func((char_u *)rfname); } // Try loading a package. if (fp == NULL && script_autoload((const char *)rfname, STRLEN(rfname), true) && !aborting()) { // Loaded a package, search for the function again. - fp = find_func(rfname); + fp = find_func((char_u *)rfname); } if (fp != NULL && (fp->uf_flags & FC_DELETED)) { error = ERROR_DELETED; - } else if (fp != NULL && (fp->uf_flags & FC_CFUNC)) { - cfunc_T cb = fp->uf_cb; - error = (*cb)(argcount, argvars, rettv, fp->uf_cb_state); + } else if (fp != NULL && (fp->uf_flags & FC_LUAREF)) { + error = typval_exec_lua_callable(fp->uf_luaref, argcount, argvars, rettv); } else if (fp != NULL) { if (funcexe->argv_func != NULL) { // postponed filling in the arguments, do it now @@ -1576,22 +1561,20 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t } else if (funcexe->basetv != NULL) { // expr->method(): Find the method name in the table, call its // implementation with the base as one of the arguments. - error = call_internal_method(fname, argcount, argvars, rettv, + error = call_internal_method((char_u *)fname, argcount, argvars, rettv, funcexe->basetv); } else { // Find the function name in the table, call its implementation. - error = call_internal_func(fname, argcount, argvars, rettv); - } - /* - * The function call (or "FuncUndefined" autocommand sequence) might - * have been aborted by an error, an interrupt, or an explicitly thrown - * exception that has not been caught so far. This situation can be - * tested for by calling aborting(). For an error in an internal - * function or for the "E132" error in call_user_func(), however, the - * throw point at which the "force_abort" flag (temporarily reset by - * emsg()) is normally updated has not been reached yet. We need to - * update that flag first to make aborting() reliable. - */ + error = call_internal_func((char_u *)fname, argcount, argvars, rettv); + } + // The function call (or "FuncUndefined" autocommand sequence) might + // have been aborted by an error, an interrupt, or an explicitly thrown + // exception that has not been caught so far. This situation can be + // tested for by calling aborting(). For an error in an internal + // function or for the "E132" error in call_user_func(), however, the + // throw point at which the "force_abort" flag (temporarily reset by + // emsg()) is normally updated has not been reached yet. We need to + // update that flag first to make aborting() reliable. update_force_abort(); } if (error == ERROR_NONE) { @@ -1602,7 +1585,7 @@ theend: // Report an error unless the argument evaluation or function call has been // cancelled due to an aborting error, an interrupt, or an exception. if (!aborting()) { - user_func_error(error, (name != NULL) ? name : (char_u *)funcname); + user_func_error(error, (name != NULL) ? (char_u *)name : (char_u *)funcname); } // clear the copies made from the partial @@ -1688,7 +1671,7 @@ static void list_func_head(ufunc_T *fp, int indent, bool force) 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; + char *name = NULL; const char_u *start; const char_u *end; int lead; @@ -1726,11 +1709,9 @@ char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, pa goto theend; } if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) { - /* - * Report an invalid expression in braces, unless the expression - * evaluation has been cancelled due to an aborting error, an - * interrupt, or an exception. - */ + // Report an invalid expression in braces, unless the expression + // evaluation has been cancelled due to an aborting error, an + // interrupt, or an exception. if (!aborting()) { if (end != NULL) { semsg(_(e_invarg2), start); @@ -1749,7 +1730,7 @@ char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, pa fdp->fd_di = lv.ll_di; } 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); + name = xstrdup(lv.ll_tv->vval.v_string); *pp = (char *)end; } else if (lv.ll_tv->v_type == VAR_PARTIAL && lv.ll_tv->vval.v_partial != NULL) { @@ -1763,7 +1744,7 @@ char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, pa memcpy(name, end + 1, (size_t)len); *pp = (char *)end + 1 + len; } else { - name = vim_strsave((char_u *)partial_name(lv.ll_tv->vval.v_partial)); + name = xstrdup(partial_name(lv.ll_tv->vval.v_partial)); *pp = (char *)end; } if (partial != NULL) { @@ -1791,28 +1772,28 @@ char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, pa // Check if the name is a Funcref. If so, use the value. if (lv.ll_exp_name != NULL) { len = (int)strlen(lv.ll_exp_name); - name = deref_func_name(lv.ll_exp_name, &len, partial, - flags & TFN_NO_AUTOLOAD); + name = (char *)deref_func_name(lv.ll_exp_name, &len, partial, + flags & TFN_NO_AUTOLOAD); if ((const char *)name == lv.ll_exp_name) { name = NULL; } } else if (!(flags & TFN_NO_DEREF)) { len = (int)(end - (char_u *)(*pp)); - name = deref_func_name((const char *)(*pp), &len, partial, - flags & TFN_NO_AUTOLOAD); - if (name == (char_u *)(*pp)) { + name = (char *)deref_func_name((const char *)(*pp), &len, partial, + flags & TFN_NO_AUTOLOAD); + if (name == *pp) { name = NULL; } } if (name != NULL) { - name = vim_strsave(name); + name = xstrdup(name); *pp = (char *)end; if (STRNCMP(name, "<SNR>", 5) == 0) { // Change "<SNR>" to the byte sequence. - name[0] = K_SPECIAL; - name[1] = KS_EXTRA; + name[0] = (char)K_SPECIAL; + name[1] = (char)KS_EXTRA; name[2] = KE_SNR; - memmove(name + 3, name + 5, strlen((char *)name + 5) + 1); + memmove(name + 3, name + 5, strlen(name + 5) + 1); } goto theend; } @@ -1875,8 +1856,8 @@ char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, pa name = xmalloc((size_t)len + (size_t)lead + 1); if (!skip && lead > 0) { - name[0] = K_SPECIAL; - name[1] = KS_EXTRA; + name[0] = (char)K_SPECIAL; + name[1] = (char)KS_EXTRA; name[2] = KE_SNR; if (sid_buf_len > 0) { // If it's "<SID>" memcpy(name + 3, sid_buf, sid_buf_len); @@ -1888,21 +1869,23 @@ char_u *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, pa theend: clear_lval(&lv); - return name; + return (char_u *)name; } +#define MAX_FUNC_NESTING 50 + /// ":function" void ex_function(exarg_T *eap) { - char_u *theline; - char_u *line_to_free = NULL; - char_u c; + char *theline; + char *line_to_free = NULL; + char c; int saved_did_emsg; bool saved_wait_return = need_wait_return; - char_u *name = NULL; - char_u *p; - char_u *arg; - char_u *line_arg = NULL; + char *name = NULL; + char *p; + char *arg; + char *line_arg = NULL; garray_T newargs; garray_T default_args; garray_T newlines; @@ -1922,22 +1905,20 @@ void ex_function(exarg_T *eap) linenr_T sourcing_lnum_off; linenr_T sourcing_lnum_top; bool is_heredoc = false; - char_u *skip_until = NULL; - char_u *heredoc_trimmed = NULL; + char *skip_until = NULL; + char *heredoc_trimmed = NULL; bool show_block = false; bool do_concat = true; - /* - * ":function" without argument: list functions. - */ + // ":function" without argument: list functions. if (ends_excmd(*eap->arg)) { if (!eap->skip) { todo = (int)func_hashtab.ht_used; - for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) { + for (hi = func_hashtab.ht_array; todo > 0 && !got_int; hi++) { if (!HASHITEM_EMPTY(hi)) { todo--; fp = HI2UF(hi); - if (message_filtered(fp->uf_name)) { + if (message_filtered((char *)fp->uf_name)) { continue; } if (!func_name_refcount(fp->uf_name)) { @@ -1946,15 +1927,13 @@ void ex_function(exarg_T *eap) } } } - eap->nextcmd = (char *)check_nextcmd((char_u *)eap->arg); + eap->nextcmd = check_nextcmd(eap->arg); return; } - /* - * ":function /pat": list functions matching pattern. - */ + // ":function /pat": list functions matching pattern. if (*eap->arg == '/') { - p = skip_regexp((char_u *)eap->arg + 1, '/', true, NULL); + p = skip_regexp(eap->arg + 1, '/', true, NULL); if (!eap->skip) { regmatch_T regmatch; @@ -1966,7 +1945,7 @@ void ex_function(exarg_T *eap) regmatch.rm_ic = p_ic; todo = (int)func_hashtab.ht_used; - for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) { + for (hi = func_hashtab.ht_array; todo > 0 && !got_int; hi++) { if (!HASHITEM_EMPTY(hi)) { todo--; fp = HI2UF(hi); @@ -1982,7 +1961,7 @@ void ex_function(exarg_T *eap) if (*p == '/') { p++; } - eap->nextcmd = (char *)check_nextcmd(p); + eap->nextcmd = check_nextcmd(p); return; } @@ -2000,15 +1979,13 @@ void ex_function(exarg_T *eap) // "fudi.fd_di" set, "fudi.fd_newkey" == NULL // s:func script-local function name // g:func global function name, same as "func" - p = (char_u *)eap->arg; - name = trans_function_name((char **)&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL); - paren = (vim_strchr((char *)p, '(') != NULL); + p = eap->arg; + name = (char *)trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL); + paren = (vim_strchr(p, '(') != NULL); if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) { - /* - * Return on an invalid expression in braces, unless the expression - * evaluation has been cancelled due to an aborting error, an - * interrupt, or an exception. - */ + // Return on an invalid expression in braces, unless the expression + // evaluation has been cancelled due to an aborting error, an + // interrupt, or an exception. if (!aborting()) { if (fudi.fd_newkey != NULL) { semsg(_(e_dictkey), fudi.fd_newkey); @@ -2016,14 +1993,14 @@ void ex_function(exarg_T *eap) xfree(fudi.fd_newkey); return; } else { - eap->skip = TRUE; + eap->skip = true; } } // An error in a function call during evaluation of an expression in magic // braces should not cause the function not to be defined. saved_did_emsg = did_emsg; - did_emsg = FALSE; + did_emsg = false; // // ":function func" with only function name: list function. @@ -2032,16 +2009,16 @@ void ex_function(exarg_T *eap) // - exclude line numbers from function body // if (!paren) { - if (!ends_excmd(*skipwhite((char *)p))) { + if (!ends_excmd(*skipwhite(p))) { semsg(_(e_trailing_arg), p); goto ret_free; } - eap->nextcmd = (char *)check_nextcmd(p); + eap->nextcmd = check_nextcmd(p); if (eap->nextcmd != NULL) { *p = NUL; } if (!eap->skip && !got_int) { - fp = find_func(name); + fp = find_func((char_u *)name); if (fp != NULL) { list_func_head(fp, !eap->forceit, eap->forceit); for (int j = 0; j < fp->uf_lines.ga_len && !got_int; j++) { @@ -2058,7 +2035,7 @@ void ex_function(exarg_T *eap) msg_putchar(' '); } } - msg_prt_line((char_u *)FUNCLINE(fp, j), false); + msg_prt_line(FUNCLINE(fp, j), false); ui_flush(); // show a line at a time os_breakcheck(); } @@ -2067,27 +2044,25 @@ void ex_function(exarg_T *eap) msg_puts(eap->forceit ? "endfunction" : " endfunction"); } } else { - emsg_funcname(N_("E123: Undefined function: %s"), name); + emsg_funcname(N_("E123: Undefined function: %s"), (char_u *)name); } } goto ret_free; } - /* - * ":function name(arg1, arg2)" Define function. - */ - p = (char_u *)skipwhite((char *)p); + // ":function name(arg1, arg2)" Define function. + p = skipwhite(p); if (*p != '(') { if (!eap->skip) { semsg(_("E124: Missing '(': %s"), eap->arg); goto ret_free; } // attempt to continue by skipping some text - if (vim_strchr((char *)p, '(') != NULL) { - p = (char_u *)vim_strchr((char *)p, '('); + if (vim_strchr(p, '(') != NULL) { + p = vim_strchr(p, '('); } } - p = (char_u *)skipwhite((char *)p + 1); + p = skipwhite(p + 1); ga_init(&newargs, (int)sizeof(char_u *), 3); ga_init(&newlines, (int)sizeof(char_u *), 3); @@ -2098,15 +2073,15 @@ void ex_function(exarg_T *eap) if (name != NULL) { arg = name; } else { - arg = fudi.fd_newkey; + arg = (char *)fudi.fd_newkey; } if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) { - int j = (*arg == K_SPECIAL) ? 3 : 0; + int j = ((uint8_t)(*arg) == K_SPECIAL) ? 3 : 0; 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); + emsg_funcname((char *)e_invarg2, (char_u *)arg); } } // Disallow using the g: dict. @@ -2115,7 +2090,7 @@ void ex_function(exarg_T *eap) } } - if (get_function_args((char **)&p, ')', &newargs, &varargs, + if (get_function_args(&p, ')', &newargs, &varargs, &default_args, eap->skip) == FAIL) { goto errret_2; } @@ -2127,7 +2102,7 @@ void ex_function(exarg_T *eap) // find extra arguments "range", "dict", "abort" and "closure" for (;;) { - p = (char_u *)skipwhite((char *)p); + p = skipwhite(p); if (STRNCMP(p, "range", 5) == 0) { flags |= FC_RANGE; p += 5; @@ -2141,9 +2116,8 @@ void ex_function(exarg_T *eap) flags |= FC_CLOSURE; p += 7; if (current_funccal == NULL) { - emsg_funcname(N_ - ("E932: Closure function should not be at top level: %s"), - name == NULL ? (char_u *)"" : name); + emsg_funcname(N_("E932: Closure function should not be at top level: %s"), + name == NULL ? (char_u *)"" : (char_u *)name); goto erret; } } else { @@ -2159,9 +2133,7 @@ void ex_function(exarg_T *eap) semsg(_(e_trailing_arg), p); } - /* - * Read the body of the function, until ":endfunction" is found. - */ + // Read the body of the function, until ":endfunction" is found. if (KeyTyped) { // Check if the function already exists, don't let the user type the // whole function before telling him it doesn't work! For a script we @@ -2169,8 +2141,8 @@ void ex_function(exarg_T *eap) if (!eap->skip && !eap->forceit) { if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) { emsg(_(e_funcdict)); - } else if (name != NULL && find_func(name) != NULL) { - emsg_funcname(e_funcexts, name); + } else if (name != NULL && find_func((char_u *)name) != NULL) { + emsg_funcname(e_funcexts, (char_u *)name); } } @@ -2199,7 +2171,7 @@ void ex_function(exarg_T *eap) if (line_arg != NULL) { // Use eap->arg, split up in parts by line breaks. theline = line_arg; - p = (char_u *)vim_strchr((char *)theline, '\n'); + p = vim_strchr(theline, '\n'); if (p == NULL) { line_arg += STRLEN(line_arg); } else { @@ -2209,9 +2181,9 @@ void ex_function(exarg_T *eap) } else { xfree(line_to_free); if (eap->getline == NULL) { - theline = getcmdline(':', 0L, indent, do_concat); + theline = (char *)getcmdline(':', 0L, indent, do_concat); } else { - theline = (char_u *)eap->getline(':', eap->cookie, indent, do_concat); + theline = eap->getline(':', eap->cookie, indent, do_concat); } line_to_free = theline; } @@ -2241,18 +2213,18 @@ void ex_function(exarg_T *eap) // * ":python <<EOF" and "EOF" // * ":let {var-name} =<< [trim] {marker}" and "{marker}" if (heredoc_trimmed == NULL - || (is_heredoc && (char_u *)skipwhite((char *)theline) == theline) + || (is_heredoc && skipwhite(theline) == theline) || STRNCMP(theline, heredoc_trimmed, STRLEN(heredoc_trimmed)) == 0) { if (heredoc_trimmed == NULL) { p = theline; } else if (is_heredoc) { - p = (char_u *)skipwhite((char *)theline) == theline + p = skipwhite(theline) == theline ? theline : theline + STRLEN(heredoc_trimmed); } else { p = theline + STRLEN(heredoc_trimmed); } - if (STRCMP(p, skip_until) == 0) { + if (strcmp(p, skip_until) == 0) { XFREE_CLEAR(skip_until); XFREE_CLEAR(heredoc_trimmed); do_concat = true; @@ -2264,27 +2236,26 @@ void ex_function(exarg_T *eap) for (p = theline; ascii_iswhite(*p) || *p == ':'; p++) {} // Check for "endfunction". - if (checkforcmd((char **)&p, "endfunction", 4) && nesting-- == 0) { + if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) { if (*p == '!') { p++; } - char_u *nextcmd = NULL; + char *nextcmd = NULL; if (*p == '|') { nextcmd = p + 1; - } else if (line_arg != NULL && *skipwhite((char *)line_arg) != NUL) { + } else if (line_arg != NULL && *skipwhite(line_arg) != NUL) { nextcmd = line_arg; } else if (*p != NUL && *p != '"' && p_verbose > 0) { - give_warning2((char_u *)_("W22: Text found after :endfunction: %s"), - p, true); + give_warning2(_("W22: Text found after :endfunction: %s"), p, true); } if (nextcmd != NULL) { // Another command follows. If the line came from "eap" we // can simply point into it, otherwise we need to change // "eap->cmdlinep". - eap->nextcmd = (char *)nextcmd; + eap->nextcmd = nextcmd; if (line_to_free != NULL) { xfree(*eap->cmdlinep); - *eap->cmdlinep = (char *)line_to_free; + *eap->cmdlinep = line_to_free; line_to_free = NULL; } } @@ -2303,20 +2274,24 @@ void ex_function(exarg_T *eap) } // Check for defining a function inside this function. - if (checkforcmd((char **)&p, "function", 2)) { + if (checkforcmd(&p, "function", 2)) { if (*p == '!') { - p = (char_u *)skipwhite((char *)p + 1); + p = skipwhite(p + 1); } p += eval_fname_script((const char *)p); - xfree(trans_function_name((char **)&p, true, 0, NULL, NULL)); - if (*skipwhite((char *)p) == '(') { - nesting++; - indent += 2; + xfree(trans_function_name(&p, true, 0, NULL, NULL)); + if (*skipwhite(p) == '(') { + if (nesting == MAX_FUNC_NESTING - 1) { + emsg(_("E1058: function nesting too deep")); + } else { + nesting++; + indent += 2; + } } } // Check for ":append", ":change", ":insert". - p = (char_u *)skip_range((char *)p, NULL); + p = skip_range(p, NULL); if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) || (p[0] == 'c' && (!ASCII_ISALPHA(p[1]) @@ -2328,11 +2303,11 @@ void ex_function(exarg_T *eap) && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) { - skip_until = vim_strsave((char_u *)"."); + skip_until = xstrdup("."); } // heredoc: Check for ":python <<EOF", ":lua <<EOF", etc. - arg = (char_u *)skipwhite((char *)skiptowhite(p)); + arg = skipwhite(skiptowhite(p)); if (arg[0] == '<' && arg[1] == '<' && ((p[0] == 'p' && p[1] == 'y' && (!ASCII_ISALNUM(p[2]) || p[2] == 't' @@ -2349,22 +2324,22 @@ void ex_function(exarg_T *eap) || (p[0] == 'm' && p[1] == 'z' && (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) { // ":python <<" continues until a dot, like ":append" - p = (char_u *)skipwhite((char *)arg + 2); + p = skipwhite(arg + 2); if (*p == NUL) { - skip_until = vim_strsave((char_u *)"."); + skip_until = xstrdup("."); } else { - skip_until = vim_strsave(p); + skip_until = xstrdup(p); } } // Check for ":let v =<< [trim] EOF" // and ":let [a, b] =<< [trim] EOF" - arg = (char_u *)skipwhite((char *)skiptowhite(p)); + arg = skipwhite(skiptowhite(p)); if (*arg == '[') { - arg = (char_u *)vim_strchr((char *)arg, ']'); + arg = vim_strchr(arg, ']'); } if (arg != NULL) { - arg = (char_u *)skipwhite((char *)skiptowhite(arg)); + arg = skipwhite(skiptowhite(arg)); if (arg[0] == '=' && arg[1] == '<' && arg[2] == '<' @@ -2372,14 +2347,13 @@ void ex_function(exarg_T *eap) && p[1] == 'e' && (!ASCII_ISALNUM(p[2]) || (p[2] == 't' && !ASCII_ISALNUM(p[3]))))) { - p = (char_u *)skipwhite((char *)arg + 3); + p = skipwhite(arg + 3); if (STRNCMP(p, "trim", 4) == 0) { // Ignore leading white space. - p = (char_u *)skipwhite((char *)p + 4); - heredoc_trimmed = - vim_strnsave(theline, (size_t)((char_u *)skipwhite((char *)theline) - theline)); + p = skipwhite(p + 4); + heredoc_trimmed = xstrnsave(theline, (size_t)(skipwhite(theline) - theline)); } - skip_until = vim_strnsave(p, (size_t)(skiptowhite(p) - p)); + skip_until = xstrnsave(p, (size_t)(skiptowhite(p) - p)); do_concat = false; is_heredoc = true; } @@ -2392,8 +2366,8 @@ void ex_function(exarg_T *eap) // Copy the line to newly allocated memory. get_one_sourceline() // allocates 250 bytes per line, this saves 80% on average. The cost // is an extra alloc/free. - p = vim_strsave(theline); - ((char **)(newlines.ga_data))[newlines.ga_len++] = (char *)p; + p = xstrdup(theline); + ((char **)(newlines.ga_data))[newlines.ga_len++] = p; // Add NULL lines for continuation lines, so that the line count is // equal to the index in the growarray. @@ -2413,30 +2387,28 @@ void ex_function(exarg_T *eap) goto erret; } - /* - * If there are no errors, add the function - */ + // If there are no errors, add the function if (fudi.fd_dict == NULL) { v = find_var((const char *)name, STRLEN(name), &ht, false); if (v != NULL && v->di_tv.v_type == VAR_FUNC) { emsg_funcname(N_("E707: Function name conflicts with variable: %s"), - name); + (char_u *)name); goto erret; } - fp = find_func(name); + fp = find_func((char_u *)name); if (fp != NULL) { // Function can be replaced with "function!" and when sourcing the // same script again, but only once. if (!eap->forceit && (fp->uf_script_ctx.sc_sid != current_sctx.sc_sid || fp->uf_script_ctx.sc_seq == current_sctx.sc_seq)) { - emsg_funcname(e_funcexts, name); + emsg_funcname(e_funcexts, (char_u *)name); goto erret; } if (fp->uf_calls > 0) { emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), - name); + (char_u *)name); goto erret; } if (fp->uf_refcount > 1) { @@ -2480,12 +2452,12 @@ void ex_function(exarg_T *eap) // Give the function a sequential number. Can only be used with a // Funcref! xfree(name); - sprintf(numbuf, "%d", ++func_nr); - name = vim_strsave((char_u *)numbuf); + sprintf(numbuf, "%d", ++func_nr); // NOLINT(runtime/printf) + name = xstrdup(numbuf); } if (fp == NULL) { - if (fudi.fd_dict == NULL && vim_strchr((char *)name, AUTOLOAD_CHAR) != NULL) { + if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) { int slen, plen; char_u *scriptname; @@ -2493,10 +2465,10 @@ void ex_function(exarg_T *eap) int j = FAIL; if (SOURCING_NAME != NULL) { scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name)); - p = (char_u *)vim_strchr((char *)scriptname, '/'); + p = vim_strchr((char *)scriptname, '/'); plen = (int)STRLEN(p); slen = (int)STRLEN(SOURCING_NAME); - if (slen > plen && FNAMECMP(p, SOURCING_NAME + slen - plen) == 0) { + if (slen > plen && path_fnamecmp(p, SOURCING_NAME + slen - plen) == 0) { j = OK; } xfree(scriptname); @@ -2524,16 +2496,16 @@ void ex_function(exarg_T *eap) tv_clear(&fudi.fd_di->di_tv); } fudi.fd_di->di_tv.v_type = VAR_FUNC; - fudi.fd_di->di_tv.vval.v_string = (char *)vim_strsave(name); + fudi.fd_di->di_tv.vval.v_string = xstrdup(name); // behave like "dict" was used flags |= FC_DICT; } // insert the new function in the function list - set_ufunc_name(fp, name); + set_ufunc_name(fp, (char_u *)name); if (overwrite) { - hi = hash_find(&func_hashtab, (char *)name); + hi = hash_find(&func_hashtab, name); hi->hi_key = UF2HIKEY(fp); } else if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) { xfree(fp); @@ -2590,8 +2562,8 @@ int eval_fname_script(const char *const p) // Use mb_strnicmp() because in Turkish comparing the "I" may not work with // the standard library function. if (p[0] == '<' - && (mb_strnicmp((char_u *)p + 1, (char_u *)"SID>", 4) == 0 - || mb_strnicmp((char_u *)p + 1, (char_u *)"SNR>", 4) == 0)) { + && (mb_strnicmp(p + 1, "SID>", 4) == 0 + || mb_strnicmp(p + 1, "SNR>", 4) == 0)) { return 5; } if (p[0] == 's' && p[1] == ':') { @@ -2666,7 +2638,7 @@ char *get_user_func_name(expand_T *xp, int idx) return (char *)fp->uf_name; // Prevent overflow. } - cat_func_name(IObuff, fp); + cat_func_name((char_u *)IObuff, fp); if (xp->xp_context != EXPAND_USER_FUNC) { STRCAT(IObuff, "("); if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args)) { @@ -2700,7 +2672,7 @@ void ex_delfunction(exarg_T *eap) semsg(_(e_trailing_arg), p); return; } - eap->nextcmd = (char *)check_nextcmd(p); + eap->nextcmd = check_nextcmd((char *)p); if (eap->nextcmd != NULL) { *p = NUL; } @@ -2853,7 +2825,7 @@ void ex_return(exarg_T *eap) { char_u *arg = (char_u *)eap->arg; typval_T rettv; - int returning = FALSE; + int returning = false; if (current_funccal == NULL) { emsg(_("E133: :return not inside a function")); @@ -2889,7 +2861,7 @@ void ex_return(exarg_T *eap) if (returning) { eap->nextcmd = NULL; } else if (eap->nextcmd == NULL) { // no argument - eap->nextcmd = (char *)check_nextcmd(arg); + eap->nextcmd = check_nextcmd((char *)arg); } if (eap->skip) { @@ -3010,7 +2982,7 @@ void ex_call(exarg_T *eap) // When inside :try we need to check for following "| catch" or "| endtry". // Not when there was an error, but do check if an exception was thrown. - if ((!aborting() || current_exception != NULL) && (!failed || eap->cstack->cs_trylevel > 0)) { + if ((!aborting() || did_throw) && (!failed || eap->cstack->cs_trylevel > 0)) { // Check for trailing illegal characters and a following command. if (!ends_excmd(*arg)) { if (!failed && !aborting()) { @@ -3018,7 +2990,7 @@ void ex_call(exarg_T *eap) semsg(_(e_trailing_arg), arg); } } else { - eap->nextcmd = (char *)check_nextcmd(arg); + eap->nextcmd = check_nextcmd((char *)arg); } } @@ -3035,8 +3007,8 @@ end: /// @param is_cmd set when called due to a ":return" command. /// @param rettv may point to a typval_T with the return rettv. /// -/// @return TRUE when the return can be carried out, -/// FALSE when the return gets pending. +/// @return true when the return can be carried out, +/// false when the return gets pending. int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) { int idx; @@ -3086,7 +3058,7 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) } report_make_pending(CSTP_RETURN, rettv); } else { - current_funccal->returned = TRUE; + current_funccal->returned = true; // If the return is carried out now, store the return value. For // a return immediately after reanimation, the value is already @@ -3105,16 +3077,16 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) /// Generate a return command for producing the value of "rettv". The result /// is an allocated string. Used by report_pending() for verbose messages. -char_u *get_return_cmd(void *rettv) +char *get_return_cmd(void *rettv) { - char_u *s = NULL; - char_u *tofree = NULL; + char *s = NULL; + char *tofree = NULL; if (rettv != NULL) { - tofree = s = (char_u *)encode_tv2echo((typval_T *)rettv, NULL); + tofree = s = encode_tv2echo((typval_T *)rettv, NULL); } if (s == NULL) { - s = (char_u *)""; + s = ""; } STRCPY(IObuff, ":return "); @@ -3123,7 +3095,7 @@ char_u *get_return_cmd(void *rettv) STRCPY(IObuff + IOSIZE - 4, "..."); } xfree(tofree); - return vim_strsave(IObuff); + return xstrdup((char *)IObuff); } /// Get next function line. @@ -3134,12 +3106,12 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat) { funccall_T *fcp = (funccall_T *)cookie; ufunc_T *fp = fcp->func; - char_u *retval; + char *retval; garray_T *gap; // growarray with function lines // 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, (char *)fp->uf_name, SOURCING_LNUM); fcp->dbg_tick = debug_tick; } if (do_profiling == PROF_YES) { @@ -3159,7 +3131,7 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat) if (fcp->linenr >= gap->ga_len) { retval = NULL; } else { - retval = (char_u *)xstrdup(((char **)(gap->ga_data))[fcp->linenr++]); + retval = xstrdup(((char **)(gap->ga_data))[fcp->linenr++]); SOURCING_LNUM = fcp->linenr; if (do_profiling == PROF_YES) { func_line_start(cookie); @@ -3169,16 +3141,16 @@ 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); + dbg_breakpoint((char *)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, (char *)fp->uf_name, SOURCING_LNUM); fcp->dbg_tick = debug_tick; } - return (char *)retval; + return retval; } -/// @return TRUE if the currently active function should be ended, because a +/// @return true if the currently active function should be ended, because a /// return was encountered or an error occurred. Used inside a ":while". int func_has_ended(void *cookie) { @@ -3190,7 +3162,7 @@ int func_has_ended(void *cookie) || fcp->returned; } -/// @return TRUE if cookie indicates a function which "abort"s on errors. +/// @return true if cookie indicates a function which "abort"s on errors. int func_has_abort(void *cookie) { return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; @@ -3211,9 +3183,9 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv) } else { fname = rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING ? (char_u *)rettv->vval.v_string - : rettv->vval.v_partial->pt_name; + : (char_u *)rettv->vval.v_partial->pt_name; // Translate "s:func" to the stored function name. - fname = fname_trans_sid(fname, fname_buf, &tofree, &error); + fname = (char_u *)fname_trans_sid((char *)fname, (char *)fname_buf, (char **)&tofree, &error); fp = find_func(fname); xfree(tofree); } @@ -3227,7 +3199,7 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv) pt->pt_auto = true; if (rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING) { // Just a function: Take over the function name and use selfdict. - pt->pt_name = (char_u *)rettv->vval.v_string; + pt->pt_name = rettv->vval.v_string; } else { partial_T *ret_pt = rettv->vval.v_partial; int i; @@ -3236,8 +3208,8 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv) // args. Can't take over name or args, the partial might // be referenced elsewhere. if (ret_pt->pt_name != NULL) { - pt->pt_name = vim_strsave(ret_pt->pt_name); - func_ref(pt->pt_name); + pt->pt_name = xstrdup(ret_pt->pt_name); + func_ref((char_u *)pt->pt_name); } else { pt->pt_func = ret_pt->pt_func; func_ptr_ref(pt->pt_func); @@ -3281,7 +3253,7 @@ int func_level(void *cookie) return ((funccall_T *)cookie)->level; } -/// @return TRUE when a function was ended by a ":return" command. +/// @return true when a function was ended by a ":return" command. int current_func_returned(void) { return current_funccal->returned; @@ -3559,7 +3531,7 @@ bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID) } if (fp_in == NULL) { - fname = fname_trans_sid(name, fname_buf, &tofree, &error); + fname = (char_u *)fname_trans_sid((char *)name, (char *)fname_buf, (char **)&tofree, &error); fp = find_func(fname); } if (fp != NULL) { @@ -3571,20 +3543,18 @@ bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID) return abort; } -/// Registers a C extension user function. -char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state) +/// Registers a luaref as a lambda. +char_u *register_luafunc(LuaRef ref) { char_u *name = get_lambda_name(); ufunc_T *fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); fp->uf_refcount = 1; fp->uf_varargs = true; - fp->uf_flags = FC_CFUNC; + fp->uf_flags = FC_LUAREF; fp->uf_calls = 0; fp->uf_script_ctx = current_sctx; - fp->uf_cb = cb; - fp->uf_cb_free = cb_free; - fp->uf_cb_state = state; + fp->uf_luaref = ref; STRCPY(fp->uf_name, name); hash_add(&func_hashtab, UF2HIKEY(fp)); diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index 4b7007aae9..9811f2afb3 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -9,6 +9,20 @@ #define HIKEY2UF(p) ((ufunc_T *)(p - offsetof(ufunc_T, uf_name))) #define HI2UF(hi) HIKEY2UF((hi)->hi_key) +// flags used in uf_flags +#define FC_ABORT 0x01 // abort function on error +#define FC_RANGE 0x02 // function accepts range +#define FC_DICT 0x04 // Dict function, uses "self" +#define FC_CLOSURE 0x08 // closure, uses outer scope variables +#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0 +#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0 +#define FC_SANDBOX 0x40 // function defined in the sandbox +#define FC_DEAD 0x80 // function kept only for reference to dfunc +#define FC_EXPORT 0x100 // "export def Func()" +#define FC_NOARGS 0x200 // no a: variables in lambda +#define FC_VIM9 0x400 // defined in vim9 script file +#define FC_LUAREF 0x800 // luaref callback + ///< Structure used by trans_function_name() typedef struct { dict_T *fd_dict; ///< Dictionary used. diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index b38849730a..bf4a9b2ca2 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -81,7 +81,7 @@ static list_T *heredoc_get(exarg_T *eap, char *cmd) // The marker is the next word. if (*cmd != NUL && *cmd != '"') { marker = skipwhite(cmd); - p = (char *)skiptowhite((char_u *)marker); + p = skiptowhite(marker); if (*skipwhite(p) != NUL && *skipwhite(p) != '"') { semsg(_(e_trailing_arg), p); return NULL; @@ -113,7 +113,7 @@ static list_T *heredoc_get(exarg_T *eap, char *cmd) && STRNCMP(theline, *eap->cmdlinep, marker_indent_len) == 0) { mi = marker_indent_len; } - if (STRCMP(marker, theline + mi) == 0) { + if (strcmp(marker, theline + mi) == 0) { xfree(theline); break; } @@ -207,7 +207,7 @@ static void ex_let_const(exarg_T *eap, const bool is_const) list_func_vars(&first); list_vim_vars(&first); } - eap->nextcmd = (char *)check_nextcmd((char_u *)arg); + eap->nextcmd = check_nextcmd(arg); } else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<') { // HERE document list_T *l = heredoc_get(eap, expr + 3); @@ -388,7 +388,7 @@ const char *skip_var_list(const char *arg, int *var_count, int *semicolon) static const char *skip_var_one(const char *arg) { if (*arg == '@' && arg[1] != NUL) { - return arg + 2; + return arg + 1 + utfc_ptr2len(arg + 1); } return (char *)find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); @@ -413,7 +413,7 @@ void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, int *firs // apply :filter /pat/ to variable name xstrlcpy(buf, prefix, IOSIZE); xstrlcat(buf, (char *)di->di_key, IOSIZE); - if (message_filtered((char_u *)buf)) { + if (message_filtered(buf)) { continue; } @@ -587,7 +587,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo char *s = vim_getenv(name); if (s != NULL) { - tofree = (char *)concat_str((const char_u *)s, (const char_u *)p); + tofree = concat_str(s, p); p = (const char *)tofree; xfree(s); } @@ -663,8 +663,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo } else if (opt_type == gov_string && stringval != NULL && s != NULL) { // string char *const oldstringval = stringval; - stringval = (char *)concat_str((const char_u *)stringval, - (const char_u *)s); + stringval = concat_str(stringval, s); xfree(oldstringval); s = stringval; } @@ -692,10 +691,14 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo return NULL; } arg++; + + int regname = utf_ptr2char(arg); + int mblen = utf_ptr2len(arg); + if (op != NULL && vim_strchr("+-*/%", *op) != NULL) { semsg(_(e_letwrong), op); } else if (endchars != NULL - && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) { + && vim_strchr(endchars, *skipwhite(arg + mblen)) == NULL) { emsg(_(e_letunexp)); } else { char *s; @@ -703,17 +706,16 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo char *ptofree = NULL; const char *p = tv_get_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { - s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); + s = get_reg_contents(*arg == '@' ? '"' : regname, kGRegExprSrc); if (s != NULL) { - ptofree = (char *)concat_str((char_u *)s, (const char_u *)p); + ptofree = concat_str(s, p); p = (const char *)ptofree; xfree(s); } } if (p != NULL) { - write_reg_contents(*arg == '@' ? '"' : *arg, - (const char_u *)p, (ssize_t)STRLEN(p), false); - arg_end = arg + 1; + write_reg_contents(*arg == '@' ? '"' : regname, p, (ssize_t)STRLEN(p), false); + arg_end = arg + mblen; } xfree(ptofree); } @@ -791,6 +793,7 @@ static void ex_unletlock(exarg_T *eap, char *argstart, int deep, ex_unletlock_ca semsg(_(e_invarg2), arg - 1); return; } + assert(*lv.ll_name == '$'); // suppress clang "Uninitialized argument value" if (!error && !eap->skip && callback(&lv, arg, eap, deep) == FAIL) { error = true; } @@ -825,7 +828,7 @@ static void ex_unletlock(exarg_T *eap, char *argstart, int deep, ex_unletlock_ca arg = skipwhite(name_end); } while (!ends_excmd(*arg)); - eap->nextcmd = (char *)check_nextcmd((char_u *)arg); + eap->nextcmd = check_nextcmd(arg); } // TODO(ZyX-I): move to eval/ex_cmds @@ -1118,7 +1121,7 @@ void vars_clear(hashtab_T *ht) vars_clear_ext(ht, true); } -/// Like vars_clear(), but only free the value if "free_val" is TRUE. +/// Like vars_clear(), but only free the value if "free_val" is true. void vars_clear_ext(hashtab_T *ht, int free_val) { int todo; @@ -1300,7 +1303,7 @@ void set_var_const(const char *name, const size_t name_len, typval_T *const tv, set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); } else if (strcmp(varname, "hlsearch") == 0) { no_hlsearch = !v->di_tv.vval.v_number; - redraw_all_later(SOME_VALID); + redraw_all_later(UPD_SOME_VALID); } return; } else if (v->di_tv.v_type != tv->v_type) { @@ -1627,7 +1630,7 @@ static void set_option_from_tv(const char *varname, typval_T *varp) strval = tv_get_string_buf_chk(varp, nbuf); } if (!error && strval != NULL) { - set_option_value(varname, numval, strval, OPT_LOCAL); + set_option_value_give_err(varname, numval, strval, OPT_LOCAL); } } @@ -1702,7 +1705,7 @@ bool var_exists(const char *var) } /// "gettabvar()" function -void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_gettabvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const varname = tv_get_string_chk(&argvars[1]); tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); @@ -1716,19 +1719,19 @@ void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "gettabwinvar()" function -void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_gettabwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getwinvar(argvars, rettv, 1); } /// "getwinvar()" function -void f_getwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_getwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { getwinvar(argvars, rettv, 0); } /// "getbufvar()" function -void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_getbufvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *const varname = tv_get_string_chk(&argvars[1]); buf_T *const buf = tv_get_buf_from_arg(&argvars[0]); @@ -1737,7 +1740,7 @@ void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "settabvar()" function -void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_settabvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->vval.v_number = 0; @@ -1768,19 +1771,19 @@ void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) } /// "settabwinvar()" function -void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_settabwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { setwinvar(argvars, rettv, 1); } /// "setwinvar()" function -void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_setwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { setwinvar(argvars, rettv, 0); } /// "setbufvar()" function -void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_setbufvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { if (check_secure() || !tv_check_str_or_nr(&argvars[0])) { |