aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval')
-rw-r--r--src/nvim/eval/decode.c6
-rw-r--r--src/nvim/eval/encode.c6
-rw-r--r--src/nvim/eval/executor.c3
-rw-r--r--src/nvim/eval/funcs.c1094
-rw-r--r--src/nvim/eval/funcs.h17
-rw-r--r--src/nvim/eval/typval.c93
-rw-r--r--src/nvim/eval/typval.h412
-rw-r--r--src/nvim/eval/typval_defs.h399
-rw-r--r--src/nvim/eval/typval_encode.c.h2
-rw-r--r--src/nvim/eval/typval_encode.h2
-rw-r--r--src/nvim/eval/userfunc.c622
-rw-r--r--src/nvim/eval/userfunc.h71
-rw-r--r--src/nvim/eval/vars.c53
13 files changed, 1388 insertions, 1392 deletions
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 7b975ce775..94ef419bed 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -4,6 +4,7 @@
#include <msgpack.h>
#include <stddef.h>
+#include "klib/kvec.h"
#include "nvim/ascii.h"
#include "nvim/charset.h" // vim_str2nr
#include "nvim/eval.h"
@@ -11,7 +12,6 @@
#include "nvim/eval/encode.h"
#include "nvim/eval/typval.h"
#include "nvim/globals.h"
-#include "nvim/lib/kvec.h"
#include "nvim/macros.h"
#include "nvim/message.h"
#include "nvim/vim.h" // OK, FAIL
@@ -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/encode.c b/src/nvim/eval/encode.c
index bb514fba47..27d35ea24f 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -13,6 +13,7 @@
#include <msgpack.h>
#include <stddef.h>
+#include "klib/kvec.h"
#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h" // vim_isprintc()
@@ -21,7 +22,6 @@
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_encode.h"
#include "nvim/garray.h"
-#include "nvim/lib/kvec.h"
#include "nvim/macros.h"
#include "nvim/math.h"
#include "nvim/mbyte.h"
@@ -219,7 +219,7 @@ bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len, cha
}
len++;
if (TV_LIST_ITEM_TV(li)->vval.v_string != NULL) {
- len += STRLEN(TV_LIST_ITEM_TV(li)->vval.v_string);
+ len += strlen(TV_LIST_ITEM_TV(li)->vval.v_string);
}
});
if (len) {
@@ -281,7 +281,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
state->offset = 0;
state->li_length = (TV_LIST_ITEM_TV(state->li)->vval.v_string == NULL
? 0
- : STRLEN(TV_LIST_ITEM_TV(state->li)->vval.v_string));
+ : strlen(TV_LIST_ITEM_TV(state->li)->vval.v_string));
}
}
*read_bytes = nbuf;
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 daeb755deb..3fff0798c4 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -195,15 +195,15 @@ int call_internal_func(const char_u *const fname, const int argcount, typval_T *
{
const EvalFuncDef *const fdef = find_internal_func((const char *)fname);
if (fdef == NULL) {
- return ERROR_UNKNOWN;
+ return FCERR_UNKNOWN;
} else if (argcount < fdef->min_argc) {
- return ERROR_TOOFEW;
+ return FCERR_TOOFEW;
} else if (argcount > fdef->max_argc) {
- return ERROR_TOOMANY;
+ return FCERR_TOOMANY;
}
argvars[argcount].v_type = VAR_UNKNOWN;
fdef->func(argvars, rettv, fdef->data);
- return ERROR_NONE;
+ return FCERR_NONE;
}
/// Invoke a method for base->method().
@@ -213,13 +213,13 @@ int call_internal_method(const char_u *const fname, const int argcount, typval_T
{
const EvalFuncDef *const fdef = find_internal_func((const char *)fname);
if (fdef == NULL) {
- return ERROR_UNKNOWN;
+ return FCERR_UNKNOWN;
} else if (fdef->base_arg == BASE_NONE) {
- return ERROR_NOTMETHOD;
+ return FCERR_NOTMETHOD;
} else if (argcount + 1 < fdef->min_argc) {
- return ERROR_TOOFEW;
+ return FCERR_TOOFEW;
} else if (argcount + 1 > fdef->max_argc) {
- return ERROR_TOOMANY;
+ return FCERR_TOOMANY;
}
typval_T argv[MAX_FUNC_ARGS + 1];
@@ -231,10 +231,10 @@ int call_internal_method(const char_u *const fname, const int argcount, typval_T
argv[argcount + 1].v_type = VAR_UNKNOWN;
fdef->func(argv, rettv, fdef->data);
- return ERROR_NONE;
+ return FCERR_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])) {
@@ -837,7 +840,7 @@ static void get_col(typval_T *argvars, typval_T *rettv, bool charcol)
if (fp->col == MAXCOL) {
// '> can be MAXCOL, get the length of the line then
if (fp->lnum <= curbuf->b_ml.ml_line_count) {
- col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
+ col = (colnr_T)strlen(ml_get(fp->lnum)) + 1;
} else {
col = MAXCOL;
}
@@ -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();
@@ -1265,7 +1270,7 @@ static void f_ctxsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// Otherwise use the column number as a byte offset.
static void set_cursorpos(typval_T *argvars, typval_T *rettv, bool charcol)
{
- long line, col;
+ long lnum, col;
long coladd = 0;
bool set_curswant = true;
@@ -1279,7 +1284,7 @@ static void set_cursorpos(typval_T *argvars, typval_T *rettv, bool charcol)
return;
}
- line = pos.lnum;
+ lnum = pos.lnum;
col = pos.col;
coladd = pos.coladd;
if (curswant >= 0) {
@@ -1288,10 +1293,15 @@ static void set_cursorpos(typval_T *argvars, typval_T *rettv, bool charcol)
}
} else if ((argvars[0].v_type == VAR_NUMBER || argvars[0].v_type == VAR_STRING)
&& (argvars[1].v_type == VAR_NUMBER || argvars[1].v_type == VAR_STRING)) {
- line = tv_get_lnum(argvars);
+ lnum = tv_get_lnum(argvars);
+ if (lnum < 0) {
+ semsg(_(e_invarg2), tv_get_string(&argvars[0]));
+ } else if (lnum == 0) {
+ lnum = curwin->w_cursor.lnum;
+ }
col = (long)tv_get_number_chk(&argvars[1], NULL);
if (charcol) {
- col = buf_charidx_to_byteidx(curbuf, (linenr_T)line, (int)col) + 1;
+ col = buf_charidx_to_byteidx(curbuf, (linenr_T)lnum, (int)col) + 1;
}
if (argvars[2].v_type != VAR_UNKNOWN) {
coladd = (long)tv_get_number_chk(&argvars[2], NULL);
@@ -1300,11 +1310,11 @@ static void set_cursorpos(typval_T *argvars, typval_T *rettv, bool charcol)
emsg(_(e_invarg));
return;
}
- if (line < 0 || col < 0 || coladd < 0) {
+ if (lnum < 0 || col < 0 || coladd < 0) {
return; // type error; errmsg already given
}
- if (line > 0) {
- curwin->w_cursor.lnum = (linenr_T)line;
+ if (lnum > 0) {
+ curwin->w_cursor.lnum = (linenr_T)lnum;
}
if (col > 0) {
curwin->w_cursor.col = (colnr_T)col - 1;
@@ -1326,20 +1336,20 @@ 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]);
if (pid == 0) {
emsg(_(e_invarg));
} else {
-#ifdef WIN32
+#ifdef MSWIN
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if (hProcess != NULL) {
@@ -1354,7 +1364,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 +1381,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 +1417,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 +1455,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 +1490,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 +1566,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 +1628,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 +1678,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);
@@ -1690,7 +1700,7 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char c = env[i][len];
env[i][len] = NUL;
-#ifdef WIN32
+#ifdef MSWIN
// Upper-case all the keys for Windows so we can detect duplicates
char *const key = strcase_save(str, true);
#else
@@ -1713,7 +1723,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 +1734,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 +1748,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 +1769,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 +1804,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 +1883,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 +1899,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 +1925,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;
@@ -1933,9 +1943,14 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(exp);
}
} else if (*p == '&' || *p == '+') { // Option.
- n = (get_option_tv(&p, NULL, true) == OK);
- if (*skipwhite(p) != NUL) {
- n = false; // Trailing garbage.
+ bool working = (*p == '+'); // whether option needs to be working
+ int opt_flags;
+
+ if (find_option_end(&p, &opt_flags) != NULL) {
+ int opt_idx = findoption(p);
+ n = (opt_idx >= 0 && (!working || get_varp_scope(get_option(opt_idx), opt_flags) != NULL));
+ } else {
+ n = false;
}
} else if (*p == '*') { // Internal or user defined function.
n = function_exists(p + 1, false);
@@ -1955,9 +1970,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 +1991,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 +2026,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 +2046,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 +2059,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 +2083,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 +2118,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 +2194,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 +2215,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 +2234,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 +2275,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 +2290,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 +2324,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 +2338,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 +2373,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 +2399,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 +2446,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 +2496,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 +2558,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 +2588,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 +2607,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 +2712,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 +2729,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 +2747,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 +2860,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 +2887,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 +2896,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 +2912,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 +2925,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 +2953,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 +2990,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 +3008,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 +3026,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 +3067,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);
}
@@ -3125,7 +3110,7 @@ static int getreg_get_regname(typval_T *argvars)
}
/// "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 +3146,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 +3166,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 +3198,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 +3215,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 +3260,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 +3314,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 +3361,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 +3399,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 +3407,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 +3449,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 +3468,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 +3499,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 +3518,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 +3527,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__)
@@ -3557,7 +3542,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#ifdef UNIX
"unix",
#endif
-#if defined(WIN32)
+#if defined(MSWIN)
"win32",
#endif
#ifdef _WIN64
@@ -3765,7 +3750,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;
@@ -3855,29 +3840,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;
@@ -3886,17 +3871,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);
@@ -3905,7 +3892,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) {
@@ -3916,7 +3903,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;
@@ -3991,19 +3978,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()");
@@ -4034,7 +4021,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--;
@@ -4048,7 +4035,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);
@@ -4056,17 +4043,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;
@@ -4139,25 +4126,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;
@@ -4199,7 +4186,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)) {
@@ -4208,14 +4195,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);
@@ -4225,7 +4212,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;
@@ -4249,7 +4236,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;
@@ -4281,7 +4268,7 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
static const char *ignored_env_vars[] = {
-#ifndef WIN32
+#ifndef MSWIN
"COLUMNS",
"LINES",
"TERMCAP",
@@ -4293,7 +4280,7 @@ static const char *ignored_env_vars[] = {
/// According to comments in src/win/process.c of libuv, Windows has a few
/// "essential" environment variables.
static const char *required_env_vars[] = {
-#ifdef WIN32
+#ifdef MSWIN
"HOMEDRIVE",
"HOMEPATH",
"LOGONSERVER",
@@ -4316,7 +4303,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);
@@ -4332,7 +4319,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
tv_dict_item_remove(env, dv);
}
}
-#ifndef WIN32
+#ifndef MSWIN
// Set COLORTERM to "truecolor" if termguicolors is set and 256
// otherwise, but only if it was set in the parent terminal at all
dictitem_T *dv = tv_dict_find(env, S_LEN("COLORTERM"));
@@ -4367,7 +4354,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
}
if (job_env) {
-#ifdef WIN32
+#ifdef MSWIN
TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, {
// Always use upper-case keys for Windows so we detect duplicate keys
char *const key = strcase_save((const char *)var->di_key, true);
@@ -4405,7 +4392,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;
@@ -4467,7 +4454,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-#ifdef WIN32
+#ifdef MSWIN
if (pty && overlapped) {
semsg(_(e_invarg2),
"job cannot have both 'pty' and 'overlapped' options set");
@@ -4480,7 +4467,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;
@@ -4525,7 +4512,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;
@@ -4558,7 +4545,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;
@@ -4657,7 +4644,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;
@@ -4691,14 +4678,28 @@ 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);
}
+/// "keytrans()" function
+static void f_keytrans(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+{
+ rettv->v_type = VAR_STRING;
+ if (tv_check_for_string_arg(argvars, 0) == FAIL
+ || argvars[0].vval.v_string == NULL) {
+ return;
+ }
+ // Need to escape K_SPECIAL for mb_unescape().
+ char *escaped = vim_strsave_escape_ks(argvars[0].vval.v_string);
+ rettv->vval.v_string = str2special_save(escaped, true, true);
+ xfree(escaped);
+}
+
/// "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;
@@ -4712,7 +4713,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:
@@ -4783,19 +4784,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;
@@ -4826,7 +4827,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) {
@@ -4840,7 +4841,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);
@@ -4854,13 +4855,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]);
@@ -4872,7 +4873,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);
}
@@ -4894,7 +4895,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) {
@@ -5008,9 +5009,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;
}
@@ -5029,8 +5030,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;
}
@@ -5065,10 +5066,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);
}
@@ -5090,31 +5091,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);
}
@@ -5169,19 +5170,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
@@ -5226,7 +5227,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];
@@ -5243,7 +5244,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) {
@@ -5382,7 +5383,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) {
@@ -5398,7 +5399,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;
@@ -5407,7 +5408,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;
}
}
@@ -5415,7 +5416,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])) {
@@ -5446,14 +5447,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;
@@ -5465,17 +5466,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;
@@ -5489,13 +5490,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--;
}
}
@@ -5503,7 +5504,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;
@@ -5525,7 +5526,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 };
@@ -5548,7 +5549,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 };
@@ -5571,7 +5572,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
@@ -5587,11 +5588,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;
@@ -5607,14 +5608,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;
@@ -5622,7 +5623,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);
}
@@ -5694,7 +5695,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;
@@ -5705,7 +5706,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);
@@ -5764,7 +5765,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;
@@ -5786,19 +5787,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;
@@ -5868,7 +5869,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);
@@ -5886,14 +5887,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;
@@ -5913,7 +5914,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;
}
@@ -5944,13 +5945,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.
@@ -5967,7 +5968,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
@@ -5982,7 +5983,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.
@@ -6002,18 +6003,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.
@@ -6069,7 +6070,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) {
@@ -6119,18 +6120,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);
}
@@ -6172,7 +6173,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;
@@ -6214,7 +6215,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;
@@ -6227,7 +6228,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");
@@ -6243,19 +6244,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) {
@@ -6292,18 +6293,18 @@ 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]);
-#ifdef WIN32
+#ifdef MSWIN
char *v = os_resolve_shortcut(fname);
if (v == NULL) {
if (os_is_reparse_point_include(fname)) {
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
{
@@ -6365,7 +6366,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;
@@ -6424,7 +6425,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) {
@@ -6461,7 +6462,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;
@@ -6486,7 +6487,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));
@@ -6508,8 +6509,8 @@ static void f_reduce(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
funcexe_T funcexe = FUNCEXE_INIT;
- funcexe.evaluate = true;
- funcexe.partial = partial;
+ funcexe.fe_evaluate = true;
+ funcexe.fe_partial = partial;
typval_T initial;
typval_T argv[3];
@@ -6786,7 +6787,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;
@@ -6821,7 +6822,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;
@@ -6910,12 +6911,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;
@@ -6982,7 +6983,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;
@@ -7000,7 +7001,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 =
@@ -7012,7 +7013,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;
@@ -7030,7 +7031,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;
@@ -7048,7 +7049,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;
@@ -7061,7 +7062,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++;
@@ -7076,45 +7077,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;
@@ -7129,11 +7104,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;
@@ -7141,7 +7116,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;
@@ -7236,13 +7211,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;
@@ -7284,7 +7259,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);
@@ -7410,18 +7385,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;
@@ -7441,7 +7421,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);
@@ -7455,7 +7435,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
@@ -7500,7 +7480,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;
@@ -7520,7 +7500,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;
@@ -7535,7 +7515,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)
{
@@ -7572,12 +7552,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));
@@ -7589,7 +7569,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));
}
@@ -7605,24 +7585,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];
@@ -7637,7 +7607,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;
@@ -7668,14 +7638,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);
}
@@ -7711,7 +7681,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;
@@ -7837,7 +7807,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) {
@@ -7852,7 +7822,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';
@@ -7903,7 +7873,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);
@@ -7914,7 +7884,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]);
@@ -7925,7 +7895,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;
@@ -7941,7 +7911,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);
@@ -7950,7 +7920,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));
@@ -8002,7 +7972,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));
@@ -8036,7 +8006,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;
@@ -8049,7 +8019,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]);
@@ -8057,7 +8027,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;
@@ -8079,7 +8049,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) {
@@ -8113,7 +8083,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;
@@ -8160,7 +8130,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;
@@ -8168,7 +8138,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;
@@ -8222,11 +8192,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];
}
@@ -8239,7 +8209,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;
@@ -8271,7 +8241,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 == '-');
@@ -8287,7 +8257,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]);
@@ -8298,7 +8268,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;
@@ -8331,7 +8301,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;
@@ -8341,7 +8311,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;
@@ -8361,13 +8331,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) {
@@ -8381,7 +8350,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);
}
@@ -8393,7 +8362,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;
@@ -8407,7 +8376,7 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- const size_t len = STRLEN(str);
+ const size_t len = strlen(str);
size_t byteidx = 0;
while (charidx >= 0 && byteidx < len) {
@@ -8421,7 +8390,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;
@@ -8453,20 +8422,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;
@@ -8489,7 +8458,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;
@@ -8498,11 +8467,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]);
@@ -8510,10 +8479,10 @@ 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);
+ const size_t slen = strlen(p);
int nbyte = 0;
bool error = false;
@@ -8564,7 +8533,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;
@@ -8610,7 +8579,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];
@@ -8624,10 +8593,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
@@ -8642,7 +8611,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]);
@@ -8653,7 +8622,7 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return; // Type error; errmsg already given.
}
- const size_t haystack_len = STRLEN(haystack);
+ const size_t haystack_len = strlen(haystack);
ptrdiff_t end_idx;
if (argvars[2].v_type != VAR_UNKNOWN) {
// Third argument: upper limit for index.
@@ -8685,14 +8654,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);
@@ -8715,7 +8684,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);
@@ -8723,7 +8692,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];
@@ -8752,14 +8721,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);
@@ -8768,12 +8737,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);
@@ -8784,7 +8753,7 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int id = 0;
if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
- && col >= 0 && (size_t)col < STRLEN(ml_get(lnum))) {
+ && col >= 0 && (size_t)col < strlen(ml_get(lnum))) {
id = syn_get_id(curwin, lnum, col, trans, NULL, false);
}
@@ -8792,7 +8761,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]);
@@ -8850,7 +8819,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
break;
case 'u':
- if (STRLEN(what) >= 9) {
+ if (strlen(what) >= 9) {
if (TOLOWER_ASC(what[5]) == 'l') {
// underline
p = highlight_has_attr(id, HL_UNDERLINE, modec);
@@ -8879,7 +8848,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]);
@@ -8893,7 +8862,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;
@@ -8909,7 +8878,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
CLEAR_FIELD(str);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count && col >= 0
- && (size_t)col <= STRLEN(ml_get(lnum)) && curwin->w_p_cole > 0) {
+ && (size_t)col <= strlen(ml_get(lnum)) && curwin->w_p_cole > 0) {
(void)syn_get_id(curwin, lnum, col, false, NULL, false);
syntax_flags = get_syntax_info(&matchid);
@@ -8935,7 +8904,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);
@@ -8946,7 +8915,7 @@ static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (lnum >= 1
&& lnum <= curbuf->b_ml.ml_line_count
&& col >= 0
- && (size_t)col <= STRLEN(ml_get(lnum))) {
+ && (size_t)col <= strlen(ml_get(lnum))) {
tv_list_alloc_ret(rettv, kListLenMayKnow);
(void)syn_get_id(curwin, lnum, col, false, NULL, true);
@@ -8959,18 +8928,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;
@@ -8992,7 +8961,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;
@@ -9078,7 +9047,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]));
@@ -9091,14 +9060,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;
}
@@ -9108,7 +9077,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]);
@@ -9126,14 +9095,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;
@@ -9176,7 +9145,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;
@@ -9256,7 +9225,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) {
@@ -9274,7 +9243,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));
@@ -9294,7 +9263,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;
@@ -9326,7 +9295,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));
@@ -9341,27 +9310,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];
@@ -9440,14 +9409,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;
@@ -9456,8 +9425,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
@@ -9495,7 +9469,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) {
@@ -9518,11 +9492,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;
@@ -9554,7 +9528,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]);
@@ -9573,7 +9547,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);
@@ -9591,7 +9565,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;
@@ -9603,7 +9577,7 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (fp->col < 0) {
fp->col = 0;
} else {
- const size_t len = STRLEN(ml_get(fp->lnum));
+ const size_t len = strlen(ml_get(fp->lnum));
if (fp->col > (colnr_T)len) {
fp->col = (colnr_T)len;
}
@@ -9616,14 +9590,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])) {
@@ -9632,7 +9606,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;
@@ -9640,20 +9614,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;
@@ -9662,7 +9636,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;
}
}
@@ -9680,25 +9654,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;
@@ -9713,7 +9699,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;
@@ -9731,7 +9717,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) {
@@ -9742,25 +9728,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;
@@ -9779,20 +9765,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];
@@ -9819,7 +9805,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;
@@ -9869,7 +9855,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;
@@ -9887,32 +9873,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;
@@ -9990,7 +9976,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..a0b06aaaf4 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;
@@ -1079,9 +1086,9 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this
funcexe_T funcexe = FUNCEXE_INIT;
- funcexe.evaluate = true;
- funcexe.partial = partial;
- funcexe.selfdict = sortinfo->item_compare_selfdict;
+ funcexe.fe_evaluate = true;
+ funcexe.fe_partial = partial;
+ funcexe.fe_selfdict = sortinfo->item_compare_selfdict;
res = call_func(func_name, -1, &rettv, 2, argv, &funcexe);
tv_clear(&argv[0]);
tv_clear(&argv[1]);
@@ -1242,20 +1249,18 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
item_compare_func_ptr = item_compare_keeping_zero;
}
- int idx = 0;
for (listitem_T *li = TV_LIST_ITEM_NEXT(l, tv_list_first(l))
; 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 +1272,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 +1573,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?
@@ -1774,7 +1779,7 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key, typval_T
tv_dict_add(argv[2].vval.v_dict, v);
}
- if (oldtv) {
+ if (oldtv && oldtv->v_type != VAR_UNKNOWN) {
dictitem_T *const v = tv_dict_item_alloc_len(S_LEN("old"));
tv_copy(oldtv, &v->di_tv);
tv_dict_add(argv[2].vval.v_dict, v);
@@ -2533,7 +2538,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 +2782,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 +2811,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 +3722,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;
}
@@ -3746,9 +3750,11 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
linenr_T tv_get_lnum(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
+ const int did_emsg_before = did_emsg;
linenr_T lnum = (linenr_T)tv_get_number_chk(tv, NULL);
- if (lnum == 0) { // No valid number, try using same function as line() does.
+ if (lnum <= 0 && did_emsg_before == did_emsg && tv->v_type != VAR_NUMBER) {
int fnum;
+ // No valid number, try using same function as line() does.
pos_T *const fp = var2fpos(tv, true, &fnum, false);
if (fp != NULL) {
lnum = fp->lnum;
@@ -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..0a4adc1f53 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -2,418 +2,19 @@
#define NVIM_EVAL_TYPVAL_H
#include <assert.h>
-#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
+#include "nvim/eval/typval_defs.h"
#include "nvim/func_attr.h"
-#include "nvim/garray.h"
#include "nvim/gettext.h"
-#include "nvim/hashtab.h"
-#include "nvim/lib/queue.h"
#include "nvim/macros.h"
#include "nvim/mbyte_defs.h"
#include "nvim/message.h"
-#include "nvim/pos.h" // for linenr_T
-#include "nvim/types.h"
-#ifdef LOG_LIST_ACTIONS
-# include "nvim/memory.h"
-#endif
-
-/// Type used for VimL VAR_NUMBER values
-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), };
-
-/// Additional values for tv_list_alloc() len argument
-enum ListLenSpecials {
- /// List length is not known in advance
- ///
- /// To be used when there is neither a way to know how many elements will be
- /// needed nor are any educated guesses.
- kListLenUnknown = -1,
- /// List length *should* be known, but is actually not
- ///
- /// All occurrences of this value should be eventually removed. This is for
- /// the case when the only reason why list length is not known is that it
- /// would be hard to code without refactoring, but refactoring is needed.
- kListLenShouldKnow = -2,
- /// List length may be known in advance, but it requires too much effort
- ///
- /// To be used when it looks impractical to determine list length.
- kListLenMayKnow = -3,
-};
-
-/// Maximal possible value of varnumber_T variable
-#define VARNUMBER_MAX INT64_MAX
-#define UVARNUMBER_MAX UINT64_MAX
-
-/// Minimal possible value of varnumber_T variable
-#define VARNUMBER_MIN INT64_MIN
-
-/// %d printf format specifier for varnumber_T
-#define PRIdVARNUMBER PRId64
-
-typedef struct listvar_S list_T;
-typedef struct dictvar_S dict_T;
-typedef struct partial_S partial_T;
-typedef struct blobvar_S blob_T;
-
-typedef struct ufunc ufunc_T;
-
-typedef enum {
- kCallbackNone = 0,
- kCallbackFuncref,
- kCallbackPartial,
- kCallbackLua,
-} CallbackType;
-
-typedef struct {
- union {
- char *funcref;
- partial_T *partial;
- LuaRef luaref;
- } data;
- CallbackType type;
-} Callback;
-
-#define CALLBACK_INIT { .type = kCallbackNone }
-#define CALLBACK_NONE ((Callback)CALLBACK_INIT)
-
-/// Structure holding dictionary watcher
-typedef struct dict_watcher {
- Callback callback;
- char *key_pattern;
- size_t key_pattern_len;
- QUEUE node;
- bool busy; // prevent recursion if the dict is changed in the callback
- bool needs_free;
-} DictWatcher;
-
-/// Bool variable values
-typedef enum {
- kBoolVarFalse, ///< v:false
- kBoolVarTrue, ///< v:true
-} BoolVarValue;
-
-/// Special variable values
-typedef enum {
- kSpecialVarNull, ///< v:null
-} SpecialVarValue;
-
-/// Variable lock status for typval_T.v_lock
-typedef enum {
- VAR_UNLOCKED = 0, ///< Not locked.
- VAR_LOCKED = 1, ///< User lock, can be unlocked.
- VAR_FIXED = 2, ///< Locked forever.
-} VarLockStatus;
-
-/// VimL variable types, for use in typval_T.v_type
-typedef enum {
- VAR_UNKNOWN = 0, ///< Unknown (unspecified) value.
- VAR_NUMBER, ///< Number, .v_number is used.
- VAR_STRING, ///< String, .v_string is used.
- VAR_FUNC, ///< Function reference, .v_string is used as function name.
- VAR_LIST, ///< List, .v_list is used.
- VAR_DICT, ///< Dictionary, .v_dict is used.
- VAR_FLOAT, ///< Floating-point value, .v_float is used.
- VAR_BOOL, ///< true, false
- VAR_SPECIAL, ///< Special value (null), .v_special
- ///< is used.
- VAR_PARTIAL, ///< Partial, .v_partial is used.
- VAR_BLOB, ///< Blob, .v_blob is used.
-} VarType;
-
-/// Structure that holds an internal variable value
-typedef struct {
- VarType v_type; ///< Variable type.
- VarLockStatus v_lock; ///< Variable lock status.
- union typval_vval_union {
- varnumber_T v_number; ///< Number, for VAR_NUMBER.
- BoolVarValue v_bool; ///< Bool value, for VAR_BOOL
- SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
- float_T v_float; ///< Floating-point number, for VAR_FLOAT.
- char *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.
- list_T *v_list; ///< List for VAR_LIST, can be NULL.
- dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL.
- partial_T *v_partial; ///< Closure: function with args.
- blob_T *v_blob; ///< Blob for VAR_BLOB, can be NULL.
- } vval; ///< Actual value.
-} typval_T;
-
-/// Values for (struct dictvar_S).dv_scope
-typedef enum {
- VAR_NO_SCOPE = 0, ///< Not a scope dictionary.
- VAR_SCOPE = 1, ///< Scope dictionary which requires prefix (a:, v:, …).
- VAR_DEF_SCOPE = 2, ///< Scope dictionary which may be accessed without prefix
- ///< (l:, g:).
-} ScopeType;
-
-/// Structure to hold an item of a list
-typedef struct listitem_S listitem_T;
-
-struct listitem_S {
- listitem_T *li_next; ///< Next item in list.
- listitem_T *li_prev; ///< Previous item in list.
- typval_T li_tv; ///< Item value.
-};
-
-/// Structure used by those that are using an item in a list
-typedef struct listwatch_S listwatch_T;
-
-struct listwatch_S {
- listitem_T *lw_item; ///< Item being watched.
- listwatch_T *lw_next; ///< Next watcher.
-};
-
-/// Structure to hold info about a list
-/// Order of members is optimized to reduce padding.
-struct listvar_S {
- listitem_T *lv_first; ///< First item, NULL if none.
- listitem_T *lv_last; ///< Last item, NULL if none.
- listwatch_T *lv_watch; ///< First watcher, NULL if none.
- listitem_T *lv_idx_item; ///< When not NULL item at index "lv_idx".
- list_T *lv_copylist; ///< Copied list used by deepcopy().
- list_T *lv_used_next; ///< next list in used lists list.
- list_T *lv_used_prev; ///< Previous list in used lists list.
- int lv_refcount; ///< Reference count.
- int lv_len; ///< Number of items.
- int lv_idx; ///< Index of a cached item, used for optimising repeated l[idx].
- int lv_copyID; ///< ID used by deepcopy().
- VarLockStatus lv_lock; ///< Zero, VAR_LOCKED, VAR_FIXED.
-
- LuaRef lua_table_ref;
-};
-
-// Static list with 10 items. Use tv_list_init_static10() to initialize.
-typedef struct {
- list_T sl_list; // must be first
- listitem_T sl_items[10];
-} staticList10_T;
-
-#define TV_LIST_STATIC10_INIT { \
- .sl_list = { \
- .lv_first = NULL, \
- .lv_last = NULL, \
- .lv_refcount = 0, \
- .lv_len = 0, \
- .lv_watch = NULL, \
- .lv_idx_item = NULL, \
- .lv_lock = VAR_FIXED, \
- .lv_used_next = NULL, \
- .lv_used_prev = NULL, \
- }, \
-}
-
-#define TV_DICTITEM_STRUCT(...) \
- struct { \
- typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
- uint8_t di_flags; /* Flags. */ \
- char_u di_key[__VA_ARGS__]; /* Key value. */ \
- }
-
-/// Structure to hold a scope dictionary
-///
-/// @warning Must be compatible with dictitem_T.
-///
-/// For use in find_var_in_ht to pretend that it found dictionary item when it
-/// finds scope dictionary.
-typedef TV_DICTITEM_STRUCT(1) ScopeDictDictItem;
-
-/// Structure to hold an item of a Dictionary
-///
-/// @warning Must be compatible with ScopeDictDictItem.
-///
-/// Also used for a variable.
-typedef TV_DICTITEM_STRUCT() dictitem_T;
-
-/// Flags for dictitem_T.di_flags
-typedef enum {
- DI_FLAGS_RO = 1, ///< Read-only value
- DI_FLAGS_RO_SBX = 2, ///< Value, read-only in the sandbox
- DI_FLAGS_FIX = 4, ///< Fixed value: cannot be :unlet or remove()d.
- DI_FLAGS_LOCK = 8, ///< Locked value.
- DI_FLAGS_ALLOC = 16, ///< Separately allocated.
-} DictItemFlags;
-
-/// Structure representing a Dictionary
-struct dictvar_S {
- VarLockStatus dv_lock; ///< Whole dictionary lock status.
- ScopeType dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
- ///< dictionary represents a scope (i.e. g:, l: …).
- int dv_refcount; ///< Reference count.
- int dv_copyID; ///< ID used when recursivery traversing a value.
- hashtab_T dv_hashtab; ///< Hashtab containing all items.
- dict_T *dv_copydict; ///< Copied dict used by deepcopy().
- dict_T *dv_used_next; ///< Next dictionary in used dictionaries list.
- dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list.
- QUEUE watchers; ///< Dictionary key watchers set by user code.
-
- LuaRef lua_table_ref;
-};
-
-/// Structure to hold info about a Blob
-struct blobvar_S {
- garray_T bv_ga; ///< Growarray with the data.
- int bv_refcount; ///< Reference count.
- VarLockStatus bv_lock; ///< VAR_UNLOCKED, VAR_LOCKED, VAR_FIXED.
-};
-
-/// Type used for script ID
-typedef int scid_T;
-/// Format argument for scid_T
-#define PRIdSCID "d"
-
-// SCript ConteXt (SCTX): identifies a script line.
-// When sourcing a script "sc_lnum" is zero, "sourcing_lnum" is the current
-// line number. When executing a user function "sc_lnum" is the line where the
-// function was defined, "sourcing_lnum" is the line number inside the
-// function. When stored with a function, mapping, option, etc. "sc_lnum" is
-// the line number in the script "sc_sid".
-typedef struct {
- scid_T sc_sid; // script ID
- int sc_seq; // sourcing sequence number
- linenr_T sc_lnum; // line number
-} sctx_T;
-
-/// Maximum number of function arguments
-#define MAX_FUNC_ARGS 20
-/// Short variable name length
-#define VAR_SHORT_LEN 20
-/// 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;
-
-struct funccall_S {
- ufunc_T *func; ///< Function being called.
- int linenr; ///< Next line to be executed.
- int returned; ///< ":return" used.
- /// Fixed variables for arguments.
- TV_DICTITEM_STRUCT(VAR_SHORT_LEN + 1) fixvar[FIXVAR_CNT];
- dict_T l_vars; ///< l: local function variables.
- ScopeDictDictItem l_vars_var; ///< Variable for l: scope.
- dict_T l_avars; ///< a: argument variables.
- ScopeDictDictItem l_avars_var; ///< Variable for a: scope.
- list_T l_varlist; ///< List for a:000.
- listitem_T l_listitems[MAX_FUNC_ARGS]; ///< List items for a:000.
- typval_T *rettv; ///< Return value.
- linenr_T breakpoint; ///< Next line with breakpoint or zero.
- int dbg_tick; ///< Debug_tick when breakpoint was set.
- int level; ///< Top nesting level of executed function.
- proftime_T prof_child; ///< Time spent in a child.
- funccall_T *caller; ///< Calling function or NULL; or next funccal in
- ///< list pointed to by previous_funccal.
- int fc_refcount; ///< Number of user functions that reference this funccall.
- int fc_copyID; ///< CopyID used for garbage collection.
- garray_T fc_funcs; ///< List of ufunc_T* which keep a reference to "func".
-};
-
-/// Structure to hold info for a user function.
-struct ufunc {
- int uf_varargs; ///< variable nr of arguments
- int uf_flags;
- int uf_calls; ///< nr of active calls
- bool uf_cleared; ///< func_clear() was already called
- garray_T uf_args; ///< arguments
- garray_T uf_def_args; ///< default argument expressions
- 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.
- // Profiling the function as a whole.
- int uf_tm_count; ///< nr of calls
- proftime_T uf_tm_total; ///< time spent in function + children
- proftime_T uf_tm_self; ///< time spent in function itself
- proftime_T uf_tm_children; ///< time spent in children this call
- // Profiling the function per line.
- int *uf_tml_count; ///< nr of times line was executed
- proftime_T *uf_tml_total; ///< time spent in a line + children
- proftime_T *uf_tml_self; ///< time spent in a line itself
- proftime_T uf_tml_start; ///< start time for current line
- proftime_T uf_tml_children; ///< time spent in children for this line
- proftime_T uf_tml_wait; ///< start wait time for current line
- int uf_tml_idx; ///< index of line being timed; -1 if none
- int uf_tml_execed; ///< line being timed was executed
- sctx_T uf_script_ctx; ///< SCTX where function was defined,
- ///< used for s: variables
- int uf_refcount; ///< reference count, see func_name_refcount()
- funccall_T *uf_scoped; ///< l: local variables for closure
- char_u *uf_name_exp; ///< if "uf_name[]" starts with SNR the name with
- ///< "<SNR>" as a string, otherwise NULL
- char_u uf_name[]; ///< Name of function (actual size equals name);
- ///< can start with <SNR>123_
- ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR)
-};
-
-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.
- typval_T *pt_argv; ///< Arguments in allocated array.
- dict_T *pt_dict; ///< Dict for "self".
-};
-
-/// Structure used for explicit stack while garbage collecting hash tables
-typedef struct ht_stack_S {
- hashtab_T *ht;
- struct ht_stack_S *prev;
-} ht_stack_T;
-
-/// Structure used for explicit stack while garbage collecting lists
-typedef struct list_stack_S {
- list_T *list;
- struct list_stack_S *prev;
-} list_stack_T;
-
-/// Structure representing one list item, used for sort array.
-typedef struct {
- listitem_T *item; ///< Sorted list item.
- int idx; ///< Sorted list item index.
-} ListSortItem;
-
-typedef int (*ListSorter)(const void *, const void *);
#ifdef LOG_LIST_ACTIONS
-
-/// List actions log entry
-typedef struct {
- uintptr_t l; ///< List log entry belongs to.
- uintptr_t li1; ///< First list item log entry belongs to, if applicable.
- uintptr_t li2; ///< Second list item log entry belongs to, if applicable.
- int len; ///< List length when log entry was created.
- const char *action; ///< Logged action.
-} ListLogEntry;
-
-typedef struct list_log ListLog;
-
-/// List actions log
-struct list_log {
- ListLog *next; ///< Next chunk or NULL.
- size_t capacity; ///< Number of entries in current chunk.
- size_t size; ///< Current chunk size.
- ListLogEntry entries[]; ///< Actual log entries.
-};
+# include "nvim/memory.h"
extern ListLog *list_log_first; ///< First list log chunk, NULL if missing
extern ListLog *list_log_last; ///< Last list log chunk
@@ -793,12 +394,6 @@ static inline void tv_init(typval_T *const tv)
}
}
-#define TV_INITIAL_VALUE \
- ((typval_T) { \
- .v_type = VAR_UNKNOWN, \
- .v_lock = VAR_UNLOCKED, \
- })
-
/// Empty string
///
/// Needed for hack which allows not allocating empty string and still not
@@ -897,9 +492,6 @@ static inline bool tv_get_float_chk(const typval_T *const tv,
float_T *const ret_f)
REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT;
-// FIXME circular dependency, cannot import message.h.
-bool semsg(const char *const fmt, ...);
-
/// Get the float value
///
/// Raises an error if object is not number or floating-point.
diff --git a/src/nvim/eval/typval_defs.h b/src/nvim/eval/typval_defs.h
new file mode 100644
index 0000000000..1c0a438751
--- /dev/null
+++ b/src/nvim/eval/typval_defs.h
@@ -0,0 +1,399 @@
+#ifndef NVIM_EVAL_TYPVAL_DEFS_H
+#define NVIM_EVAL_TYPVAL_DEFS_H
+
+#include <inttypes.h>
+#include <limits.h>
+
+#include "nvim/garray.h"
+#include "nvim/hashtab.h"
+#include "nvim/lib/queue.h"
+#include "nvim/pos.h"
+#include "nvim/types.h"
+
+/// Type used for VimL VAR_NUMBER values
+typedef int64_t varnumber_T;
+typedef uint64_t uvarnumber_T;
+
+/// Refcount for dict or list that should not be freed
+enum { DO_NOT_FREE_CNT = (INT_MAX / 2), };
+
+/// Additional values for tv_list_alloc() len argument
+enum ListLenSpecials {
+ /// List length is not known in advance
+ ///
+ /// To be used when there is neither a way to know how many elements will be
+ /// needed nor are any educated guesses.
+ kListLenUnknown = -1,
+ /// List length *should* be known, but is actually not
+ ///
+ /// All occurrences of this value should be eventually removed. This is for
+ /// the case when the only reason why list length is not known is that it
+ /// would be hard to code without refactoring, but refactoring is needed.
+ kListLenShouldKnow = -2,
+ /// List length may be known in advance, but it requires too much effort
+ ///
+ /// To be used when it looks impractical to determine list length.
+ kListLenMayKnow = -3,
+};
+
+/// Maximal possible value of varnumber_T variable
+#define VARNUMBER_MAX INT64_MAX
+#define UVARNUMBER_MAX UINT64_MAX
+
+/// Minimal possible value of varnumber_T variable
+#define VARNUMBER_MIN INT64_MIN
+
+/// %d printf format specifier for varnumber_T
+#define PRIdVARNUMBER PRId64
+
+typedef struct listvar_S list_T;
+typedef struct dictvar_S dict_T;
+typedef struct partial_S partial_T;
+typedef struct blobvar_S blob_T;
+
+typedef struct ufunc ufunc_T;
+
+typedef enum {
+ kCallbackNone = 0,
+ kCallbackFuncref,
+ kCallbackPartial,
+ kCallbackLua,
+} CallbackType;
+
+typedef struct {
+ union {
+ char *funcref;
+ partial_T *partial;
+ LuaRef luaref;
+ } data;
+ CallbackType type;
+} Callback;
+
+#define CALLBACK_INIT { .type = kCallbackNone }
+#define CALLBACK_NONE ((Callback)CALLBACK_INIT)
+
+/// Structure holding dictionary watcher
+typedef struct dict_watcher {
+ Callback callback;
+ char *key_pattern;
+ size_t key_pattern_len;
+ QUEUE node;
+ bool busy; // prevent recursion if the dict is changed in the callback
+ bool needs_free;
+} DictWatcher;
+
+/// Bool variable values
+typedef enum {
+ kBoolVarFalse, ///< v:false
+ kBoolVarTrue, ///< v:true
+} BoolVarValue;
+
+/// Special variable values
+typedef enum {
+ kSpecialVarNull, ///< v:null
+} SpecialVarValue;
+
+/// Variable lock status for typval_T.v_lock
+typedef enum {
+ VAR_UNLOCKED = 0, ///< Not locked.
+ VAR_LOCKED = 1, ///< User lock, can be unlocked.
+ VAR_FIXED = 2, ///< Locked forever.
+} VarLockStatus;
+
+/// VimL variable types, for use in typval_T.v_type
+typedef enum {
+ VAR_UNKNOWN = 0, ///< Unknown (unspecified) value.
+ VAR_NUMBER, ///< Number, .v_number is used.
+ VAR_STRING, ///< String, .v_string is used.
+ VAR_FUNC, ///< Function reference, .v_string is used as function name.
+ VAR_LIST, ///< List, .v_list is used.
+ VAR_DICT, ///< Dictionary, .v_dict is used.
+ VAR_FLOAT, ///< Floating-point value, .v_float is used.
+ VAR_BOOL, ///< true, false
+ VAR_SPECIAL, ///< Special value (null), .v_special is used.
+ VAR_PARTIAL, ///< Partial, .v_partial is used.
+ VAR_BLOB, ///< Blob, .v_blob is used.
+} VarType;
+
+/// Structure that holds an internal variable value
+typedef struct {
+ VarType v_type; ///< Variable type.
+ VarLockStatus v_lock; ///< Variable lock status.
+ union typval_vval_union {
+ varnumber_T v_number; ///< Number, for VAR_NUMBER.
+ BoolVarValue v_bool; ///< Bool value, for VAR_BOOL
+ SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
+ float_T v_float; ///< Floating-point number, for VAR_FLOAT.
+ char *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.
+ list_T *v_list; ///< List for VAR_LIST, can be NULL.
+ dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL.
+ partial_T *v_partial; ///< Closure: function with args.
+ blob_T *v_blob; ///< Blob for VAR_BLOB, can be NULL.
+ } vval; ///< Actual value.
+} typval_T;
+
+#define TV_INITIAL_VALUE \
+ ((typval_T) { \
+ .v_type = VAR_UNKNOWN, \
+ .v_lock = VAR_UNLOCKED, \
+ })
+
+/// Values for (struct dictvar_S).dv_scope
+typedef enum {
+ VAR_NO_SCOPE = 0, ///< Not a scope dictionary.
+ VAR_SCOPE = 1, ///< Scope dictionary which requires prefix (a:, v:, …).
+ VAR_DEF_SCOPE = 2, ///< Scope dictionary which may be accessed without prefix
+ ///< (l:, g:).
+} ScopeType;
+
+/// Structure to hold an item of a list
+typedef struct listitem_S listitem_T;
+
+struct listitem_S {
+ listitem_T *li_next; ///< Next item in list.
+ listitem_T *li_prev; ///< Previous item in list.
+ typval_T li_tv; ///< Item value.
+};
+
+/// Structure used by those that are using an item in a list
+typedef struct listwatch_S listwatch_T;
+
+struct listwatch_S {
+ listitem_T *lw_item; ///< Item being watched.
+ listwatch_T *lw_next; ///< Next watcher.
+};
+
+/// Structure to hold info about a list
+/// Order of members is optimized to reduce padding.
+struct listvar_S {
+ listitem_T *lv_first; ///< First item, NULL if none.
+ listitem_T *lv_last; ///< Last item, NULL if none.
+ listwatch_T *lv_watch; ///< First watcher, NULL if none.
+ listitem_T *lv_idx_item; ///< When not NULL item at index "lv_idx".
+ list_T *lv_copylist; ///< Copied list used by deepcopy().
+ list_T *lv_used_next; ///< next list in used lists list.
+ list_T *lv_used_prev; ///< Previous list in used lists list.
+ int lv_refcount; ///< Reference count.
+ int lv_len; ///< Number of items.
+ int lv_idx; ///< Index of a cached item, used for optimising repeated l[idx].
+ int lv_copyID; ///< ID used by deepcopy().
+ VarLockStatus lv_lock; ///< Zero, VAR_LOCKED, VAR_FIXED.
+
+ LuaRef lua_table_ref;
+};
+
+/// Static list with 10 items. Use tv_list_init_static10() to initialize.
+typedef struct {
+ list_T sl_list; // must be first
+ listitem_T sl_items[10];
+} staticList10_T;
+
+#define TV_LIST_STATIC10_INIT { \
+ .sl_list = { \
+ .lv_first = NULL, \
+ .lv_last = NULL, \
+ .lv_refcount = 0, \
+ .lv_len = 0, \
+ .lv_watch = NULL, \
+ .lv_idx_item = NULL, \
+ .lv_lock = VAR_FIXED, \
+ .lv_used_next = NULL, \
+ .lv_used_prev = NULL, \
+ }, \
+}
+
+#define TV_DICTITEM_STRUCT(...) \
+ struct { \
+ typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
+ uint8_t di_flags; /* Flags. */ \
+ char_u di_key[__VA_ARGS__]; /* Key value. */ \
+ }
+
+/// Structure to hold a scope dictionary
+///
+/// @warning Must be compatible with dictitem_T.
+///
+/// For use in find_var_in_ht to pretend that it found dictionary item when it
+/// finds scope dictionary.
+typedef TV_DICTITEM_STRUCT(1) ScopeDictDictItem;
+
+/// Structure to hold an item of a Dictionary
+///
+/// @warning Must be compatible with ScopeDictDictItem.
+///
+/// Also used for a variable.
+typedef TV_DICTITEM_STRUCT() dictitem_T;
+
+/// Flags for dictitem_T.di_flags
+typedef enum {
+ DI_FLAGS_RO = 1, ///< Read-only value
+ DI_FLAGS_RO_SBX = 2, ///< Value, read-only in the sandbox
+ DI_FLAGS_FIX = 4, ///< Fixed value: cannot be :unlet or remove()d.
+ DI_FLAGS_LOCK = 8, ///< Locked value.
+ DI_FLAGS_ALLOC = 16, ///< Separately allocated.
+} DictItemFlags;
+
+/// Structure representing a Dictionary
+struct dictvar_S {
+ VarLockStatus dv_lock; ///< Whole dictionary lock status.
+ ScopeType dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
+ ///< dictionary represents a scope (i.e. g:, l: …).
+ int dv_refcount; ///< Reference count.
+ int dv_copyID; ///< ID used when recursivery traversing a value.
+ hashtab_T dv_hashtab; ///< Hashtab containing all items.
+ dict_T *dv_copydict; ///< Copied dict used by deepcopy().
+ dict_T *dv_used_next; ///< Next dictionary in used dictionaries list.
+ dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list.
+ QUEUE watchers; ///< Dictionary key watchers set by user code.
+
+ LuaRef lua_table_ref;
+};
+
+/// Structure to hold info about a Blob
+struct blobvar_S {
+ garray_T bv_ga; ///< Growarray with the data.
+ int bv_refcount; ///< Reference count.
+ VarLockStatus bv_lock; ///< VAR_UNLOCKED, VAR_LOCKED, VAR_FIXED.
+};
+
+/// Type used for script ID
+typedef int scid_T;
+/// Format argument for scid_T
+#define PRIdSCID "d"
+
+/// SCript ConteXt (SCTX): identifies a script line.
+/// When sourcing a script "sc_lnum" is zero, "sourcing_lnum" is the current
+/// line number. When executing a user function "sc_lnum" is the line where the
+/// function was defined, "sourcing_lnum" is the line number inside the
+/// function. When stored with a function, mapping, option, etc. "sc_lnum" is
+/// the line number in the script "sc_sid".
+typedef struct {
+ scid_T sc_sid; ///< script ID
+ int sc_seq; ///< sourcing sequence number
+ linenr_T sc_lnum; ///< line number
+} sctx_T;
+
+/// Maximum number of function arguments
+enum { MAX_FUNC_ARGS = 20, };
+/// Short variable name length
+enum { VAR_SHORT_LEN = 20, };
+/// Number of fixed variables used for arguments
+enum { FIXVAR_CNT = 12, };
+
+/// Structure to hold info for a function that is currently being executed.
+typedef struct funccall_S funccall_T;
+
+struct funccall_S {
+ ufunc_T *func; ///< Function being called.
+ int linenr; ///< Next line to be executed.
+ int returned; ///< ":return" used.
+ /// Fixed variables for arguments.
+ TV_DICTITEM_STRUCT(VAR_SHORT_LEN + 1) fixvar[FIXVAR_CNT];
+ dict_T l_vars; ///< l: local function variables.
+ ScopeDictDictItem l_vars_var; ///< Variable for l: scope.
+ dict_T l_avars; ///< a: argument variables.
+ ScopeDictDictItem l_avars_var; ///< Variable for a: scope.
+ list_T l_varlist; ///< List for a:000.
+ listitem_T l_listitems[MAX_FUNC_ARGS]; ///< List items for a:000.
+ typval_T *rettv; ///< Return value.
+ linenr_T breakpoint; ///< Next line with breakpoint or zero.
+ int dbg_tick; ///< debug_tick when breakpoint was set.
+ int level; ///< Top nesting level of executed function.
+ proftime_T prof_child; ///< Time spent in a child.
+ funccall_T *caller; ///< Calling function or NULL; or next funccal in
+ ///< list pointed to by previous_funccal.
+ int fc_refcount; ///< Number of user functions that reference this funccall.
+ int fc_copyID; ///< CopyID used for garbage collection.
+ garray_T fc_funcs; ///< List of ufunc_T* which keep a reference to "func".
+};
+
+/// Structure to hold info for a user function.
+struct ufunc {
+ int uf_varargs; ///< variable nr of arguments
+ int uf_flags;
+ int uf_calls; ///< nr of active calls
+ bool uf_cleared; ///< func_clear() was already called
+ garray_T uf_args; ///< arguments
+ garray_T uf_def_args; ///< default argument expressions
+ garray_T uf_lines; ///< function lines
+ int uf_profiling; ///< true when func is being profiled
+ int uf_prof_initialized;
+ 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
+ proftime_T uf_tm_self; ///< time spent in function itself
+ proftime_T uf_tm_children; ///< time spent in children this call
+ // Profiling the function per line.
+ int *uf_tml_count; ///< nr of times line was executed
+ proftime_T *uf_tml_total; ///< time spent in a line + children
+ proftime_T *uf_tml_self; ///< time spent in a line itself
+ proftime_T uf_tml_start; ///< start time for current line
+ proftime_T uf_tml_children; ///< time spent in children for this line
+ proftime_T uf_tml_wait; ///< start wait time for current line
+ int uf_tml_idx; ///< index of line being timed; -1 if none
+ int uf_tml_execed; ///< line being timed was executed
+ sctx_T uf_script_ctx; ///< SCTX where function was defined,
+ ///< used for s: variables
+ int uf_refcount; ///< reference count, see func_name_refcount()
+ funccall_T *uf_scoped; ///< l: local variables for closure
+ char_u *uf_name_exp; ///< if "uf_name[]" starts with SNR the name with
+ ///< "<SNR>" as a string, otherwise NULL
+ char_u uf_name[]; ///< Name of function (actual size equals name);
+ ///< can start with <SNR>123_
+ ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR)
+};
+
+struct partial_S {
+ 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".
+};
+
+/// Structure used for explicit stack while garbage collecting hash tables
+typedef struct ht_stack_S {
+ hashtab_T *ht;
+ struct ht_stack_S *prev;
+} ht_stack_T;
+
+/// Structure used for explicit stack while garbage collecting lists
+typedef struct list_stack_S {
+ list_T *list;
+ struct list_stack_S *prev;
+} list_stack_T;
+
+/// Structure representing one list item, used for sort array.
+typedef struct {
+ listitem_T *item; ///< Sorted list item.
+ int idx; ///< Sorted list item index.
+} ListSortItem;
+
+typedef int (*ListSorter)(const void *, const void *);
+
+#ifdef LOG_LIST_ACTIONS
+/// List actions log entry
+typedef struct {
+ uintptr_t l; ///< List log entry belongs to.
+ uintptr_t li1; ///< First list item log entry belongs to, if applicable.
+ uintptr_t li2; ///< Second list item log entry belongs to, if applicable.
+ int len; ///< List length when log entry was created.
+ const char *action; ///< Logged action.
+} ListLogEntry;
+
+typedef struct list_log ListLog;
+
+/// List actions log
+struct list_log {
+ ListLog *next; ///< Next chunk or NULL.
+ size_t capacity; ///< Number of entries in current chunk.
+ size_t size; ///< Current chunk size.
+ ListLogEntry entries[]; ///< Actual log entries.
+};
+#endif
+
+#endif // NVIM_EVAL_TYPVAL_DEFS_H
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index 73b36b8611..ff4f92e40b 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -250,7 +250,7 @@
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_encode.h"
#include "nvim/func_attr.h"
-#include "nvim/lib/kvec.h"
+#include "klib/kvec.h"
// -V::1063
diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h
index ed70ba87ec..33e19c531c 100644
--- a/src/nvim/eval/typval_encode.h
+++ b/src/nvim/eval/typval_encode.h
@@ -10,9 +10,9 @@
#include <stddef.h>
#include <string.h>
+#include "klib/kvec.h"
#include "nvim/eval/typval.h"
#include "nvim/func_attr.h"
-#include "nvim/lib/kvec.h"
/// Type of the stack entry
typedef enum {
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index c46cb6ba5d..b0a56c4440 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;
}
@@ -439,12 +425,12 @@ int get_func_tv(const char_u *name, int len, typval_T *rettv, char **arg, funcex
// Get the arguments.
argp = *arg;
while (argcount < MAX_FUNC_ARGS
- - (funcexe->partial == NULL ? 0 : funcexe->partial->pt_argc)) {
+ - (funcexe->fe_partial == NULL ? 0 : funcexe->fe_partial->pt_argc)) {
argp = skipwhite(argp + 1); // skip the '(' or ','
if (*argp == ')' || *argp == ',' || *argp == NUL) {
break;
}
- if (eval1(&argp, &argvars[argcount], funcexe->evaluate) == FAIL) {
+ if (eval1(&argp, &argvars[argcount], funcexe->fe_evaluate) == FAIL) {
ret = FAIL;
break;
}
@@ -525,39 +511,38 @@ 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);
- if (llen > 0) {
- fname_buf[0] = K_SPECIAL;
- fname_buf[1] = KS_EXTRA;
- fname_buf[2] = KE_SNR;
- int i = 3;
- if (eval_fname_sid((const char *)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 "_",
- (int64_t)current_sctx.sc_sid);
- i = (int)STRLEN(fname_buf);
- }
- }
- if ((size_t)i + STRLEN(name + llen) < FLEN_FIXED) {
- STRCPY(fname_buf + i, name + llen);
- fname = fname_buf;
+ const int llen = eval_fname_script(name);
+ if (llen == 0) {
+ return (char *)name; // no prefix
+ }
+
+ fname_buf[0] = (char)K_SPECIAL;
+ fname_buf[1] = (char)KS_EXTRA;
+ fname_buf[2] = KE_SNR;
+ int i = 3;
+ if (eval_fname_sid(name)) { // "<SID>" or "s:"
+ if (current_sctx.sc_sid <= 0) {
+ *error = FCERR_SCRIPT;
} else {
- fname = xmalloc((size_t)i + STRLEN(name + llen) + 1);
- *tofree = fname;
- memmove(fname, fname_buf, (size_t)i);
- STRCPY(fname + i, name + llen);
+ snprintf(fname_buf + i, (size_t)(FLEN_FIXED + 1 - i), "%" PRId64 "_",
+ (int64_t)current_sctx.sc_sid);
+ i = (int)strlen(fname_buf);
}
+ }
+ char *fname;
+ if ((size_t)i + strlen(name + llen) < FLEN_FIXED) {
+ STRCPY(fname_buf + i, name + llen);
+ fname = fname_buf;
} else {
- fname = (char_u *)name;
+ fname = xmalloc((size_t)i + strlen(name + llen) + 1);
+ *tofree = fname;
+ memmove(fname, fname_buf, (size_t)i);
+ STRCPY(fname + i, name + llen);
}
-
return fname;
}
@@ -758,9 +743,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);
@@ -852,7 +837,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
@@ -863,7 +848,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.
@@ -893,7 +878,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).
@@ -970,11 +955,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);
@@ -1058,7 +1043,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;
@@ -1071,7 +1056,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();
}
@@ -1083,7 +1068,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;
@@ -1213,6 +1198,34 @@ static bool func_name_refcount(char_u *name)
return isdigit(*name) || *name == '<';
}
+/// Call a user function after checking the arguments.
+static int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv,
+ funcexe_T *funcexe, dict_T *selfdict)
+ FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5)
+{
+ if (fp->uf_flags & FC_LUAREF) {
+ return typval_exec_lua_callable(fp->uf_luaref, argcount, argvars, rettv);
+ }
+
+ if ((fp->uf_flags & FC_RANGE) && funcexe->fe_doesrange != NULL) {
+ *funcexe->fe_doesrange = true;
+ }
+ int error;
+ if (argcount < fp->uf_args.ga_len - fp->uf_def_args.ga_len) {
+ error = FCERR_TOOFEW;
+ } else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) {
+ error = FCERR_TOOMANY;
+ } else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) {
+ error = FCERR_DICT;
+ } else {
+ // Call the user function.
+ call_user_func(fp, argcount, argvars, rettv, funcexe->fe_firstline, funcexe->fe_lastline,
+ (fp->uf_flags & FC_DICT) ? selfdict : NULL);
+ error = FCERR_NONE;
+ }
+ return error;
+}
+
static funccal_entry_T *funccal_stack = NULL;
/// Save the current function call pointer, and set it to NULL.
@@ -1353,11 +1366,11 @@ int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict
});
funcexe_T funcexe = FUNCEXE_INIT;
- funcexe.firstline = curwin->w_cursor.lnum;
- funcexe.lastline = curwin->w_cursor.lnum;
- funcexe.evaluate = true;
- funcexe.partial = partial;
- funcexe.selfdict = selfdict;
+ funcexe.fe_firstline = curwin->w_cursor.lnum;
+ funcexe.fe_lastline = curwin->w_cursor.lnum;
+ funcexe.fe_evaluate = true;
+ funcexe.fe_partial = partial;
+ funcexe.fe_selfdict = selfdict;
r = call_func((char *)name, -1, rettv, argc, argv, &funcexe);
func_call_skip_call:
@@ -1375,27 +1388,27 @@ static void user_func_error(int error, const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
switch (error) {
- case ERROR_UNKNOWN:
+ case FCERR_UNKNOWN:
emsg_funcname(N_("E117: Unknown function: %s"), name);
break;
- case ERROR_NOTMETHOD:
+ case FCERR_NOTMETHOD:
emsg_funcname(N_("E276: Cannot use function as a method: %s"), name);
break;
- case ERROR_DELETED:
+ case FCERR_DELETED:
emsg_funcname(N_("E933: Function was deleted: %s"), name);
break;
- case ERROR_TOOMANY:
+ case FCERR_TOOMANY:
emsg_funcname(_(e_toomanyarg), name);
break;
- case ERROR_TOOFEW:
+ case FCERR_TOOFEW:
emsg_funcname(N_("E119: Not enough arguments for function: %s"),
name);
break;
- case ERROR_SCRIPT:
+ case FCERR_SCRIPT:
emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
name);
break;
- case ERROR_DICT:
+ case FCERR_DICT:
emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
name);
break;
@@ -1435,27 +1448,27 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t
FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
{
int ret = FAIL;
- int error = ERROR_NONE;
+ int error = FCERR_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;
+ dict_T *selfdict = funcexe->fe_selfdict;
typval_T argv[MAX_FUNC_ARGS + 1]; // used when "partial" or
- // "funcexe->basetv" is not NULL
+ // "funcexe->fe_basetv" is not NULL
int argv_clear = 0;
int argv_base = 0;
- partial_T *partial = funcexe->partial;
+ partial_T *partial = funcexe->fe_partial;
// Initialize rettv so that it is safe for caller to invoke clear_tv(rettv)
// even when call_func() returns FAIL.
rettv->v_type = VAR_UNKNOWN;
if (len <= 0) {
- len = (int)STRLEN(funcname);
+ len = (int)strlen(funcname);
}
if (partial != NULL) {
fp = partial->pt_func;
@@ -1463,12 +1476,12 @@ 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) {
- *funcexe->doesrange = false;
+ if (funcexe->fe_doesrange != NULL) {
+ *funcexe->fe_doesrange = false;
}
if (partial != NULL) {
@@ -1478,10 +1491,10 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t
if (partial->pt_dict != NULL && (selfdict == NULL || !partial->pt_auto)) {
selfdict = partial->pt_dict;
}
- if (error == ERROR_NONE && partial->pt_argc > 0) {
+ if (error == FCERR_NONE && partial->pt_argc > 0) {
for (argv_clear = 0; argv_clear < partial->pt_argc; argv_clear++) {
if (argv_clear + argcount_in >= MAX_FUNC_ARGS) {
- error = ERROR_TOOMANY;
+ error = FCERR_TOOMANY;
goto theend;
}
tv_copy(&partial->pt_argv[argv_clear], &argv[argv_clear]);
@@ -1494,8 +1507,8 @@ 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;
+ if (error == FCERR_NONE && funcexe->fe_evaluate) {
+ char *rfname = fname;
// Ignore "g:" before a function name.
if (fp == NULL && fname[0] == 'g' && fname[1] == ':') {
@@ -1504,12 +1517,12 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t
rettv->v_type = VAR_NUMBER; // default rettv is number zero
rettv->vval.v_number = 0;
- error = ERROR_UNKNOWN;
+ error = FCERR_UNKNOWN;
if (is_luafunc(partial)) {
if (len > 0) {
- error = ERROR_NONE;
- argv_add_base(funcexe->basetv, &argvars, &argcount, argv, &argv_base);
+ error = FCERR_NONE;
+ argv_add_base(funcexe->fe_basetv, &argvars, &argcount, argv, &argv_base);
nlua_typval_call(funcname, (size_t)len, argvars, argcount, rettv);
} else {
// v:lua was called directly; show its name in the emsg
@@ -1519,76 +1532,55 @@ 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),
+ 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);
+ error = FCERR_DELETED;
} else if (fp != NULL) {
- if (funcexe->argv_func != NULL) {
+ if (funcexe->fe_argv_func != NULL) {
// postponed filling in the arguments, do it now
- argcount = funcexe->argv_func(argcount, argvars, argv_clear,
- fp->uf_args.ga_len);
+ argcount = funcexe->fe_argv_func(argcount, argvars, argv_clear, fp);
}
- argv_add_base(funcexe->basetv, &argvars, &argcount, argv, &argv_base);
+ argv_add_base(funcexe->fe_basetv, &argvars, &argcount, argv, &argv_base);
- if (fp->uf_flags & FC_RANGE && funcexe->doesrange != NULL) {
- *funcexe->doesrange = true;
- }
- if (argcount < fp->uf_args.ga_len - fp->uf_def_args.ga_len) {
- error = ERROR_TOOFEW;
- } else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) {
- error = ERROR_TOOMANY;
- } else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) {
- error = ERROR_DICT;
- } else {
- // Call the user function.
- call_user_func(fp, argcount, argvars, rettv, funcexe->firstline,
- funcexe->lastline,
- (fp->uf_flags & FC_DICT) ? selfdict : NULL);
- error = ERROR_NONE;
- }
+ error = call_user_func_check(fp, argcount, argvars, rettv, funcexe, selfdict);
}
- } else if (funcexe->basetv != NULL) {
+ } else if (funcexe->fe_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,
- funcexe->basetv);
+ error = call_internal_method((char_u *)fname, argcount, argvars, rettv,
+ funcexe->fe_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) {
+ if (error == FCERR_NONE) {
ret = OK;
}
@@ -1596,7 +1588,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
@@ -1682,7 +1674,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;
@@ -1720,11 +1712,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);
@@ -1743,7 +1733,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) {
@@ -1757,7 +1747,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) {
@@ -1785,28 +1775,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;
}
@@ -1869,8 +1859,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);
@@ -1882,21 +1872,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;
@@ -1916,22 +1908,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)) {
@@ -1940,15 +1930,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;
@@ -1960,7 +1948,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);
@@ -1976,7 +1964,7 @@ void ex_function(exarg_T *eap)
if (*p == '/') {
p++;
}
- eap->nextcmd = (char *)check_nextcmd(p);
+ eap->nextcmd = check_nextcmd(p);
return;
}
@@ -1994,15 +1982,20 @@ 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;
+ if (strncmp(p, "<lambda>", 8) == 0) {
+ p += 8;
+ (void)getdigits(&p, false, 0);
+ name = xstrndup(eap->arg, (size_t)(p - eap->arg));
+ CLEAR_FIELD(fudi);
+ } else {
+ 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);
@@ -2010,14 +2003,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.
@@ -2026,16 +2019,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++) {
@@ -2052,7 +2045,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();
}
@@ -2061,27 +2054,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);
@@ -2092,15 +2083,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.
@@ -2109,7 +2100,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;
}
@@ -2121,7 +2112,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;
@@ -2135,9 +2126,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 {
@@ -2153,9 +2143,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
@@ -2163,8 +2151,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);
}
}
@@ -2193,9 +2181,9 @@ 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);
+ line_arg += strlen(line_arg);
} else {
*p = NUL;
line_arg = p + 1;
@@ -2203,9 +2191,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;
}
@@ -2235,18 +2223,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) {
+ strlen(heredoc_trimmed)) == 0) {
if (heredoc_trimmed == NULL) {
p = theline;
} else if (is_heredoc) {
- p = (char_u *)skipwhite((char *)theline) == theline
- ? theline : theline + STRLEN(heredoc_trimmed);
+ p = skipwhite(theline) == theline
+ ? theline : theline + strlen(heredoc_trimmed);
} else {
- p = theline + STRLEN(heredoc_trimmed);
+ 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;
@@ -2258,27 +2246,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;
}
}
@@ -2297,20 +2284,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])
@@ -2322,11 +2313,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'
@@ -2343,22 +2334,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] == '<'
@@ -2366,14 +2357,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;
}
@@ -2386,8 +2376,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.
@@ -2407,30 +2397,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);
+ 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) {
@@ -2474,23 +2462,23 @@ 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;
// Check that the autoload name matches the script name.
int j = FAIL;
if (SOURCING_NAME != NULL) {
- scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name));
- p = (char_u *)vim_strchr((char *)scriptname, '/');
+ scriptname = (char_u *)autoload_name((const char *)name, strlen(name));
+ 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);
@@ -2502,7 +2490,7 @@ void ex_function(exarg_T *eap)
}
}
- fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
+ fp = xcalloc(1, offsetof(ufunc_T, uf_name) + strlen(name) + 1);
if (fudi.fd_dict != NULL) {
if (fudi.fd_di == NULL) {
@@ -2518,16 +2506,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);
@@ -2584,8 +2572,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] == ':') {
@@ -2660,7 +2648,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)) {
@@ -2694,7 +2682,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;
}
@@ -2847,7 +2835,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"));
@@ -2883,7 +2871,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) {
@@ -2969,12 +2957,12 @@ void ex_call(exarg_T *eap)
arg = startarg;
funcexe_T funcexe = FUNCEXE_INIT;
- funcexe.firstline = eap->line1;
- funcexe.lastline = eap->line2;
- funcexe.doesrange = &doesrange;
- funcexe.evaluate = true;
- funcexe.partial = partial;
- funcexe.selfdict = fudi.fd_dict;
+ funcexe.fe_firstline = eap->line1;
+ funcexe.fe_lastline = eap->line2;
+ funcexe.fe_doesrange = &doesrange;
+ funcexe.fe_evaluate = true;
+ funcexe.fe_partial = partial;
+ funcexe.fe_selfdict = fudi.fd_dict;
if (get_func_tv(name, -1, &rettv, (char **)&arg, &funcexe) == FAIL) {
failed = true;
break;
@@ -3004,7 +2992,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()) {
@@ -3012,7 +3000,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);
}
}
@@ -3029,8 +3017,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;
@@ -3080,7 +3068,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
@@ -3099,25 +3087,25 @@ 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 ");
STRLCPY(IObuff + 8, s, IOSIZE - 8);
- if (STRLEN(s) + 8 >= IOSIZE) {
+ if (strlen(s) + 8 >= IOSIZE) {
STRCPY(IObuff + IOSIZE - 4, "...");
}
xfree(tofree);
- return vim_strsave(IObuff);
+ return xstrdup((char *)IObuff);
}
/// Get next function line.
@@ -3128,12 +3116,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) {
@@ -3153,7 +3141,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);
@@ -3163,16 +3151,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)
{
@@ -3184,7 +3172,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;
@@ -3205,9 +3193,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);
}
@@ -3221,7 +3209,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;
@@ -3230,8 +3218,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);
@@ -3275,7 +3263,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;
@@ -3543,7 +3531,7 @@ bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
{
ufunc_T *fp = fp_in;
funccall_T *fc;
- int error = ERROR_NONE;
+ int error = FCERR_NONE;
char_u fname_buf[FLEN_FIXED + 1];
char_u *tofree = NULL;
char_u *fname;
@@ -3553,7 +3541,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) {
@@ -3565,20 +3553,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..4098622a14 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.
@@ -24,44 +38,43 @@ struct funccal_entry {
/// errors for when calling a function
typedef enum {
- ERROR_UNKNOWN = 0,
- ERROR_TOOMANY,
- ERROR_TOOFEW,
- ERROR_SCRIPT,
- ERROR_DICT,
- ERROR_NONE,
- ERROR_OTHER,
- ERROR_BOTH,
- ERROR_DELETED,
- ERROR_NOTMETHOD,
+ FCERR_UNKNOWN = 0,
+ FCERR_TOOMANY = 1,
+ FCERR_TOOFEW = 2,
+ FCERR_SCRIPT = 3,
+ FCERR_DICT = 4,
+ FCERR_NONE = 5,
+ FCERR_OTHER = 6,
+ FCERR_DELETED = 7,
+ FCERR_NOTMETHOD = 8, ///< function cannot be used as a method
} FnameTransError;
/// Used in funcexe_T. Returns the new argcount.
-typedef int (*ArgvFunc)(int current_argcount, typval_T *argv, int argskip,
- int called_func_argcount);
+typedef int (*ArgvFunc)(int current_argcount, typval_T *argv, int partial_argcount,
+ ufunc_T *called_func);
/// Structure passed between functions dealing with function call execution.
typedef struct {
- ArgvFunc argv_func; ///< when not NULL, can be used to fill in arguments only
- ///< when the invoked function uses them
- linenr_T firstline; ///< first line of range
- linenr_T lastline; ///< last line of range
- bool *doesrange; ///< [out] if not NULL: function handled range
- bool evaluate; ///< actually evaluate expressions
- partial_T *partial; ///< for extra arguments
- dict_T *selfdict; ///< Dictionary for "self"
- typval_T *basetv; ///< base for base->method()
+ ArgvFunc fe_argv_func; ///< when not NULL, can be used to fill in arguments only
+ ///< when the invoked function uses them
+ linenr_T fe_firstline; ///< first line of range
+ linenr_T fe_lastline; ///< last line of range
+ bool *fe_doesrange; ///< [out] if not NULL: function handled range
+ bool fe_evaluate; ///< actually evaluate expressions
+ partial_T *fe_partial; ///< for extra arguments
+ dict_T *fe_selfdict; ///< Dictionary for "self"
+ typval_T *fe_basetv; ///< base for base->method()
} funcexe_T;
#define FUNCEXE_INIT (funcexe_T) { \
- .argv_func = NULL, \
- .firstline = 0, \
- .lastline = 0, \
- .doesrange = NULL, \
- .evaluate = false, \
- .partial = NULL, \
- .selfdict = NULL, \
- .basetv = NULL, \
+ .fe_argv_func = NULL, \
+ .fe_firstline = 0, \
+ .fe_lastline = 0, \
+ .fe_doesrange = NULL, \
+ .fe_evaluate = false, \
+ .fe_partial = NULL, \
+ .fe_selfdict = NULL, \
+ .fe_basetv = NULL, \
}
#define FUNCARG(fp, j) ((char **)(fp->uf_args.ga_data))[j]
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c
index b38849730a..4d7214205d 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);
@@ -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;
}
@@ -705,14 +704,13 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
if (p != NULL && op != NULL && *op == '.') {
s = get_reg_contents(*arg == '@' ? '"' : *arg, 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);
+ write_reg_contents(*arg == '@' ? '"' : *arg, p, (ssize_t)strlen(p), false);
arg_end = arg + 1;
}
xfree(ptofree);
@@ -791,6 +789,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 +824,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 +1117,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 +1299,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) {
@@ -1349,12 +1348,8 @@ void set_var_const(const char *name, const size_t name_len, typval_T *const tv,
}
if (watched) {
- if (oldtv.v_type == VAR_UNKNOWN) {
- tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, NULL);
- } else {
- tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
- tv_clear(&oldtv);
- }
+ tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
+ tv_clear(&oldtv);
}
if (is_const) {
@@ -1627,7 +1622,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 +1697,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 +1711,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 +1732,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 +1763,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])) {
@@ -1802,7 +1797,7 @@ void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// reset notion of buffer
aucmd_restbuf(&aco);
} else {
- const size_t varname_len = STRLEN(varname);
+ const size_t varname_len = strlen(varname);
char *const bufvarname = xmalloc(varname_len + 3);
buf_T *const save_curbuf = curbuf;
curbuf = buf;