aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval')
-rw-r--r--src/nvim/eval/decode.c20
-rw-r--r--src/nvim/eval/encode.c67
-rw-r--r--src/nvim/eval/executor.c4
-rw-r--r--src/nvim/eval/funcs.c3312
-rw-r--r--src/nvim/eval/funcs.h7
-rw-r--r--src/nvim/eval/typval.c135
-rw-r--r--src/nvim/eval/typval.h28
-rw-r--r--src/nvim/eval/typval_encode.c.h9
-rw-r--r--src/nvim/eval/typval_encode.h4
-rw-r--r--src/nvim/eval/userfunc.c456
10 files changed, 1620 insertions, 2422 deletions
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 797420c150..7b975ce775 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -290,8 +290,7 @@ typval_T decode_string(const char *const s, const size_t len, const TriState has
return (typval_T) {
.v_type = VAR_STRING,
.v_lock = VAR_UNLOCKED,
- .vval = { .v_string = (char_u *)(
- (s == NULL || s_allocated) ? (char *)s : xmemdupz(s, len)) },
+ .vval = { .v_string = ((s == NULL || s_allocated) ? (char *)s : xmemdupz(s, len)) },
};
}
}
@@ -376,7 +375,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
"inside string: %.*s"), LENP(p, e));
goto parse_json_string_fail;
}
- const int ch = utf_ptr2char((char_u *)p);
+ const int ch = utf_ptr2char(p);
// All characters above U+007F are encoded using two or more bytes
// and thus cannot possibly be equal to *p. But utf_ptr2char({0xFF,
// 0}) will return 0xFF, even though 0xFF cannot start any UTF-8
@@ -393,7 +392,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
goto parse_json_string_fail;
}
const size_t ch_len = (size_t)utf_char2len(ch);
- assert(ch_len == (size_t)(ch ? utf_ptr2len((char_u *)p) : 1));
+ assert(ch_len == (size_t)(ch ? utf_ptr2len(p) : 1));
len += ch_len;
p += ch_len;
}
@@ -415,9 +414,9 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
bool hasnul = false;
#define PUT_FST_IN_PAIR(fst_in_pair, str_end) \
do { \
- if (fst_in_pair != 0) { \
- str_end += utf_char2bytes(fst_in_pair, (char_u *)str_end); \
- fst_in_pair = 0; \
+ if ((fst_in_pair) != 0) { \
+ (str_end) += utf_char2bytes(fst_in_pair, (str_end)); \
+ (fst_in_pair) = 0; \
} \
} while (0)
for (const char *t = s; t < p; t++) {
@@ -441,15 +440,14 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
fst_in_pair = (int)ch;
} else if (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END
&& fst_in_pair != 0) {
- const int full_char = (
- (int)(ch - SURROGATE_LO_START)
+ const int full_char = ((int)(ch - SURROGATE_LO_START)
+ ((fst_in_pair - SURROGATE_HI_START) << 10)
+ SURROGATE_FIRST_CHAR);
- str_end += utf_char2bytes(full_char, (char_u *)str_end);
+ str_end += utf_char2bytes(full_char, str_end);
fst_in_pair = 0;
} else {
PUT_FST_IN_PAIR(fst_in_pair, str_end);
- str_end += utf_char2bytes((int)ch, (char_u *)str_end);
+ str_end += utf_char2bytes((int)ch, str_end);
}
break;
}
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 6f4357421b..090939666d 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -29,8 +29,6 @@
#include "nvim/message.h"
#include "nvim/vim.h" // For _()
-#define utf_char2len(b) ((size_t)utf_char2len(b))
-
const char *const encode_bool_var_names[] = {
[kBoolVarTrue] = "true",
[kBoolVarFalse] = "false",
@@ -69,10 +67,10 @@ int encode_list_write(void *const data, const char *const buf, const size_t len)
line_end = xmemscan(buf, NL, len);
if (line_end != buf) {
const size_t line_length = (size_t)(line_end - buf);
- char *str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string;
+ char *str = TV_LIST_ITEM_TV(li)->vval.v_string;
const size_t li_len = (str == NULL ? 0 : strlen(str));
TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(str, li_len + line_length + 1);
- str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
+ str = TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
memcpy(str, buf, line_length);
str[line_length] = 0;
memchrsub(str, NUL, NL, line_length);
@@ -132,9 +130,10 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
case kMPConvDict: {
typval_T key_tv = {
.v_type = VAR_STRING,
- .vval = { .v_string = (v.data.d.hi == NULL
- ? v.data.d.dict->dv_hashtab.ht_array
- : (v.data.d.hi - 1))->hi_key },
+ .vval = { .v_string =
+ (char *)(v.data.d.hi ==
+ NULL ? v.data.d.dict->dv_hashtab.ht_array : (v.data.d.hi -
+ 1))->hi_key },
};
char *const key = encode_tv2string(&key_tv, NULL);
vim_snprintf((char *)IObuff, IOSIZE, key_msg, key);
@@ -265,7 +264,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
|| TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) {
assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
- const char ch = (char)(TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
+ const char ch = TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++];
*p++ = (char)(ch == (char)NL ? (char)NUL : ch);
}
if (p < buf_end) {
@@ -294,8 +293,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
- const char *const buf_ = (const char *)buf; \
- if (buf == NULL) { \
+ const char *const buf_ = (const char *)(buf); \
+ if ((buf) == NULL) { \
ga_concat(gap, "''"); \
} else { \
const size_t len_ = (len); \
@@ -384,14 +383,14 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len) \
do { \
- if (len != 0) { \
+ if ((len) != 0) { \
ga_concat(gap, ", "); \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len) \
do { \
- if ((ptrdiff_t)len != -1) { \
+ if ((ptrdiff_t)(len) != -1) { \
ga_concat(gap, ", "); \
} \
} while (0)
@@ -453,12 +452,12 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
size_t backref = 0; \
for (; backref < kv_size(*mpstack); backref++) { \
const MPConvStackVal mpval = kv_A(*mpstack, backref); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict) { \
+ if (mpval.type == (conv_type)) { \
+ if ((conv_type) == kMPConvDict) { \
if ((void *)mpval.data.d.dict == (void *)(val)) { \
break; \
} \
- } else if (conv_type == kMPConvList) { \
+ } else if ((conv_type) == kMPConvList) { \
if ((void *)mpval.data.l.list == (void *)(val)) { \
break; \
} \
@@ -488,19 +487,19 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
size_t backref = 0; \
for (; backref < kv_size(*mpstack); backref++) { \
const MPConvStackVal mpval = kv_A(*mpstack, backref); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict) { \
- if ((void *)mpval.data.d.dict == (void *)val) { \
+ if (mpval.type == (conv_type)) { \
+ if ((conv_type) == kMPConvDict) { \
+ if ((void *)mpval.data.d.dict == (void *)(val)) { \
break; \
} \
- } else if (conv_type == kMPConvList) { \
- if ((void *)mpval.data.l.list == (void *)val) { \
+ } else if ((conv_type) == kMPConvList) { \
+ if ((void *)mpval.data.l.list == (void *)(val)) { \
break; \
} \
} \
} \
} \
- if (conv_type == kMPConvDict) { \
+ if ((conv_type) == kMPConvDict) { \
vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{...@%zu}", backref); \
} else { \
vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "[...@%zu]", backref); \
@@ -610,10 +609,10 @@ static inline int convert_to_json_string(garray_T *const gap, const char *const
// This is done to make resulting values displayable on screen also not from
// Neovim.
#define ENCODE_RAW(ch) \
- (ch >= 0x20 && utf_printable(ch))
+ ((ch) >= 0x20 && utf_printable(ch))
for (size_t i = 0; i < utf_len;) {
- const int ch = utf_ptr2char((char_u *)utf_buf + i);
- const size_t shift = (ch == 0 ? 1 : ((size_t)utf_ptr2len((char_u *)utf_buf + i)));
+ const int ch = utf_ptr2char(utf_buf + i);
+ const size_t shift = (ch == 0 ? 1 : ((size_t)utf_ptr2len(utf_buf + i)));
assert(shift > 0);
i += shift;
switch (ch) {
@@ -652,11 +651,11 @@ static inline int convert_to_json_string(garray_T *const gap, const char *const
ga_append(gap, '"');
ga_grow(gap, (int)str_len);
for (size_t i = 0; i < utf_len;) {
- const int ch = utf_ptr2char((char_u *)utf_buf + i);
- const size_t shift = (ch == 0? 1: utf_char2len(ch));
+ const int ch = utf_ptr2char(utf_buf + i);
+ const size_t shift = (ch == 0 ? 1 : ((size_t)utf_char2len(ch)));
assert(shift > 0);
// Is false on invalid unicode, but this should already be handled.
- assert(ch == 0 || shift == ((size_t)utf_ptr2len((char_u *)utf_buf + i)));
+ assert(ch == 0 || shift == ((size_t)utf_ptr2len(utf_buf + i)));
switch (ch) {
case BS:
case TAB:
@@ -789,7 +788,7 @@ bool encode_check_json_key(const typval_T *const tv)
#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key) \
do { \
- if (!encode_check_json_key(&key)) { \
+ if (!encode_check_json_key(&(key))) { \
emsg(_("E474: Invalid key in special dictionary")); \
goto label; \
} \
@@ -871,7 +870,7 @@ char *encode_tv2echo(typval_T *tv, size_t *len)
ga_init(&ga, (int)sizeof(char), 80);
if (tv->v_type == VAR_STRING || tv->v_type == VAR_FUNC) {
if (tv->vval.v_string != NULL) {
- ga_concat(&ga, (char *)tv->vval.v_string);
+ ga_concat(&ga, tv->vval.v_string);
}
} else {
const int eve_ret = encode_vim_to_echo(&ga, tv, N_(":echo argument"));
@@ -912,7 +911,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
- if (buf == NULL) { \
+ if ((buf) == NULL) { \
msgpack_pack_bin(packer, 0); \
} else { \
const size_t len_ = (len); \
@@ -923,7 +922,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
do { \
- if (buf == NULL) { \
+ if ((buf) == NULL) { \
msgpack_pack_str(packer, 0); \
} else { \
const size_t len_ = (len); \
@@ -934,11 +933,11 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
do { \
- if (buf == NULL) { \
- msgpack_pack_ext(packer, 0, (int8_t)type); \
+ if ((buf) == NULL) { \
+ msgpack_pack_ext(packer, 0, (int8_t)(type)); \
} else { \
const size_t len_ = (len); \
- msgpack_pack_ext(packer, len_, (int8_t)type); \
+ msgpack_pack_ext(packer, len_, (int8_t)(type)); \
msgpack_pack_ext_body(packer, buf, len_); \
} \
} while (0)
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
index ed4f36f4c7..3e66150180 100644
--- a/src/nvim/eval/executor.c
+++ b/src/nvim/eval/executor.c
@@ -63,7 +63,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *cons
if (tv2->v_type == VAR_LIST) {
break;
}
- if (vim_strchr((char_u *)"+-*/%", *op) != NULL) {
+ if (vim_strchr("+-*/%", *op) != NULL) {
// nr += nr or nr -= nr, nr *= nr, nr /= nr, nr %= nr
varnumber_T n = tv_get_number(tv1);
if (tv2->v_type == VAR_FLOAT) {
@@ -114,7 +114,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *cons
numbuf));
tv_clear(tv1);
tv1->v_type = VAR_STRING;
- tv1->vval.v_string = (char_u *)s;
+ tv1->vval.v_string = s;
}
return OK;
case VAR_FLOAT: {
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 875655d0b3..7bed21e99b 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -16,27 +16,31 @@
#include "nvim/context.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
+#include "nvim/digraph.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/decode.h"
#include "nvim/eval/encode.h"
#include "nvim/eval/executor.h"
#include "nvim/eval/funcs.h"
+#include "nvim/eval/typval.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/globals.h"
+#include "nvim/highlight_group.h"
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/input.h"
#include "nvim/lua/executor.h"
#include "nvim/macros.h"
+#include "nvim/mapping.h"
#include "nvim/mark.h"
+#include "nvim/match.h"
#include "nvim/math.h"
#include "nvim/memline.h"
#include "nvim/mouse.h"
@@ -61,11 +65,12 @@
#include "nvim/state.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
+#include "nvim/testing.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/vim.h"
-
+#include "nvim/window.h"
/// Describe data to return from find_some_match()
typedef enum {
@@ -76,9 +81,6 @@ typedef enum {
kSomeMatchStrPos, ///< Data for matchstrpos().
} SomeMatchType;
-KHASH_MAP_INIT_STR(functions, VimLFuncDef)
-
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/funcs.c.generated.h"
@@ -96,10 +98,9 @@ PRAGMA_DIAG_POP
PRAGMA_DIAG_POP
#endif
-
-static char *e_listarg = N_("E686: Argument of %s must be a List");
static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
static char *e_invalwindow = N_("E957: Invalid window number");
+static char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value");
/// Dummy va_list for passing to vim_snprintf
///
@@ -109,10 +110,9 @@ static char *e_invalwindow = N_("E957: Invalid window number");
/// - using va_start() to initialize it gives "function with fixed args" error
static va_list dummy_ap;
-
/// Function given to ExpandGeneric() to obtain the list of internal
/// or user defined function names.
-char_u *get_function_name(expand_T *xp, int idx)
+char *get_function_name(expand_T *xp, int idx)
{
static int intidx = -1;
char_u *name;
@@ -121,24 +121,20 @@ char_u *get_function_name(expand_T *xp, int idx)
intidx = -1;
}
if (intidx < 0) {
- name = get_user_func_name(xp, idx);
+ name = (char_u *)get_user_func_name(xp, idx);
if (name != NULL) {
if (*name != NUL && *name != '<'
&& STRNCMP("g:", xp->xp_pattern, 2) == 0) {
- return cat_prefix_varname('g', name);
+ return cat_prefix_varname('g', (char *)name);
}
- return name;
+ return (char *)name;
}
}
- while ((size_t)++intidx < ARRAY_SIZE(functions)
- && functions[intidx].name[0] == '\0') {
- }
- if ((size_t)intidx >= ARRAY_SIZE(functions)) {
+ const char *const key = functions[++intidx].name;
+ if (!key) {
return NULL;
}
-
- const char *const key = functions[intidx].name;
const size_t key_len = strlen(key);
memcpy(IObuff, key, key_len);
IObuff[key_len] = '(';
@@ -148,12 +144,12 @@ char_u *get_function_name(expand_T *xp, int idx)
} else {
IObuff[key_len + 1] = NUL;
}
- return IObuff;
+ return (char *)IObuff;
}
/// Function given to ExpandGeneric() to obtain the list of internal or
/// user defined variable or function names.
-char_u *get_expr_name(expand_T *xp, int idx)
+char *get_expr_name(expand_T *xp, int idx)
{
static int intidx = -1;
char_u *name;
@@ -162,9 +158,9 @@ char_u *get_expr_name(expand_T *xp, int idx)
intidx = -1;
}
if (intidx < 0) {
- name = get_function_name(xp, idx);
+ name = (char_u *)get_function_name(xp, idx);
if (name != NULL) {
- return name;
+ return (char *)name;
}
}
return get_user_var_name(xp, ++intidx);
@@ -174,19 +170,20 @@ char_u *get_expr_name(expand_T *xp, int idx)
///
/// @param[in] name Name of the function.
///
-/// Returns pointer to the function definition or NULL if not found.
-const VimLFuncDef *find_internal_func(const char *const name)
+/// @return pointer to the function definition or NULL if not found.
+const EvalFuncDef *find_internal_func(const char *const name)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL
{
size_t len = strlen(name);
- return find_internal_func_gperf(name, len);
+ int index = find_internal_func_hash(name, len);
+ return index >= 0 ? &functions[index] : NULL;
}
int call_internal_func(const char_u *const fname, const int argcount, typval_T *const argvars,
typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL
{
- const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ const EvalFuncDef *const fdef = find_internal_func((const char *)fname);
if (fdef == NULL) {
return ERROR_UNKNOWN;
} else if (argcount < fdef->min_argc) {
@@ -204,7 +201,7 @@ int call_internal_method(const char_u *const fname, const int argcount, typval_T
typval_T *const rettv, typval_T *const basetv)
FUNC_ATTR_NONNULL_ALL
{
- const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ const EvalFuncDef *const fdef = find_internal_func((const char *)fname);
if (fdef == NULL) {
return ERROR_UNKNOWN;
} else if (fdef->base_arg == BASE_NONE) {
@@ -228,9 +225,7 @@ int call_internal_method(const char_u *const fname, const int argcount, typval_T
return ERROR_NONE;
}
-/*
- * Return TRUE for a non-zero Number and a non-empty String.
- */
+/// @return TRUE for a non-zero Number and a non-empty String.
static int non_zero_arg(typval_T *argvars)
{
return ((argvars[0].v_type == VAR_NUMBER
@@ -242,11 +237,11 @@ static int non_zero_arg(typval_T *argvars)
&& *argvars[0].vval.v_string != NUL));
}
-// Apply a floating point C function on a typval with one float_T.
-//
-// 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
+/// Apply a floating point C function on a typval with one float_T.
+///
+/// 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)
{
float_T f;
@@ -292,9 +287,7 @@ end:
api_clear_error(&err);
}
-/*
- * "abs(expr)" function
- */
+/// "abs(expr)" function
static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type == VAR_FLOAT) {
@@ -314,9 +307,7 @@ static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "add(list, item)" function
- */
+/// "add(list, item)" function
static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 1; // Default: failed.
@@ -344,16 +335,13 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "and(expr, expr)" function
- */
+/// "and(expr, expr)" function
static void f_and(typval_T *argvars, typval_T *rettv, FunPtr 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)
{
@@ -362,7 +350,7 @@ static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
api_free_dictionary(metadata);
}
-// "append(lnum, string/list)" function
+/// "append(lnum, string/list)" function
static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(&argvars[0]);
@@ -370,7 +358,7 @@ static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_buffer_lines(curbuf, lnum, true, &argvars[1], rettv);
}
-// "appendbufline(buf, lnum, string/list)" function
+/// "appendbufline(buf, lnum, string/list)" function
static void f_appendbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *const buf = tv_get_buf(&argvars[0], false);
@@ -402,9 +390,7 @@ static void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "argidx()" function
- */
+/// "argidx()" function
static void f_argidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = curwin->w_arg_idx;
@@ -420,9 +406,7 @@ static void f_arglistid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "argv(nr)" function
- */
+/// "argv(nr)" function
static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
aentry_T *arglist = NULL;
@@ -448,7 +432,7 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = NULL;
int idx = tv_get_number_chk(&argvars[0], NULL);
if (arglist != NULL && idx >= 0 && idx < argcount) {
- rettv->vval.v_string = (char_u *)xstrdup((const char *)alist_name(&arglist[idx]));
+ rettv->vval.v_string = xstrdup((const char *)alist_name(&arglist[idx]));
} else if (idx == -1) {
get_arglist_as_rettv(arglist, argcount, rettv);
}
@@ -457,93 +441,7 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "assert_beeps(cmd [, error])" function
-static void f_assert_beeps(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_beeps(argvars, false);
-}
-
-// "assert_nobeep(cmd [, error])" function
-static void f_assert_nobeep(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_beeps(argvars, true);
-}
-
-// "assert_equal(expected, actual[, msg])" function
-static void f_assert_equal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
-}
-
-// "assert_equalfile(fname-one, fname-two[, msg])" function
-static void f_assert_equalfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_equalfile(argvars);
-}
-
-// "assert_notequal(expected, actual[, msg])" function
-static void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
-}
-
-/// "assert_report(msg)
-static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- garray_T ga;
-
- prepare_assert_error(&ga);
- ga_concat(&ga, tv_get_string(&argvars[0]));
- assert_error(&ga);
- ga_clear(&ga);
- rettv->vval.v_number = 1;
-}
-
-/// "assert_exception(string[, msg])" function
-static void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_exception(argvars);
-}
-
-/// "assert_fails(cmd [, error [, msg]])" function
-static void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_fails(argvars);
-}
-
-// "assert_false(actual[, msg])" function
-static void f_assert_false(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_bool(argvars, false);
-}
-
-/// "assert_inrange(lower, upper[, msg])" function
-static void f_assert_inrange(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_inrange(argvars);
-}
-
-/// "assert_match(pattern, actual[, msg])" function
-static void f_assert_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
-}
-
-/// "assert_notmatch(pattern, actual[, msg])" function
-static void f_assert_notmatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
-}
-
-// "assert_true(actual[, msg])" function
-static void f_assert_true(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_bool(argvars, true);
-}
-
-/*
- * "atan2()" function
- */
+/// "atan2()" function
static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T fx;
@@ -557,27 +455,20 @@ static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "browse(save, title, initdir, default)" function
- */
+/// "browse(save, title, initdir, default)" function
static void f_browse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
}
-/*
- * "browsedir(title, initdir)" function
- */
+/// "browsedir(title, initdir)" function
static void f_browsedir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
f_browse(argvars, rettv, NULL);
}
-
-/*
- * Find a buffer by number or exact name.
- */
+/// Find a buffer by number or exact name.
static buf_T *find_buffer(typval_T *avar)
{
buf_T *buf = NULL;
@@ -591,9 +482,7 @@ static buf_T *find_buffer(typval_T *avar)
* buffer, these don't use the full path. */
FOR_ALL_BUFFERS(bp) {
if (bp->b_fname != NULL
- && (path_with_url((char *)bp->b_fname)
- || bt_nofile(bp)
- )
+ && (path_with_url(bp->b_fname) || bt_nofilename(bp))
&& STRCMP(bp->b_fname, avar->vval.v_string) == 0) {
buf = bp;
break;
@@ -604,25 +493,21 @@ static buf_T *find_buffer(typval_T *avar)
return buf;
}
-// "bufadd(expr)" function
+/// "bufadd(expr)" function
static void f_bufadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *name = (char_u *)tv_get_string(&argvars[0]);
- rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0);
+ rettv->vval.v_number = buflist_add(*name == NUL ? NULL : (char *)name, 0);
}
-/*
- * "bufexists(expr)" function
- */
+/// "bufexists(expr)" function
static void f_bufexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
}
-/*
- * "buflisted(expr)" function
- */
+/// "buflisted(expr)" function
static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -631,7 +516,7 @@ static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
}
-// "bufload(expr)" function
+/// "bufload(expr)" function
static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr)
{
buf_T *buf = get_buf_arg(&argvars[0]);
@@ -646,9 +531,7 @@ static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr)
}
}
-/*
- * "bufloaded(expr)" function
- */
+/// "bufloaded(expr)" function
static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -657,9 +540,7 @@ static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
}
-/*
- * "bufname(expr)" function
- */
+/// "bufname(expr)" function
static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const buf_T *buf;
@@ -671,13 +552,11 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
buf = tv_get_buf_from_arg(&argvars[0]);
}
if (buf != NULL && buf->b_fname != NULL) {
- rettv->vval.v_string = (char_u *)xstrdup((char *)buf->b_fname);
+ rettv->vval.v_string = xstrdup(buf->b_fname);
}
}
-/*
- * "bufnr(expr)" function
- */
+/// "bufnr(expr)" function
static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const buf_T *buf;
@@ -707,7 +586,7 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
&& tv_get_number_chk(&argvars[1], &error) != 0
&& !error
&& (name = tv_get_string_chk(&argvars[0])) != NULL) {
- buf = buflist_new((char_u *)name, NULL, 1, 0);
+ buf = buflist_new((char *)name, NULL, 1, 0);
}
if (buf != NULL) {
@@ -749,14 +628,12 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
buf_win_common(argvars, rettv, true);
}
-/*
- * Get buffer by number or pattern.
- */
+/// Get buffer by number or pattern.
buf_T *tv_get_buf(typval_T *tv, int curtab_only)
{
- char_u *name = tv->vval.v_string;
+ char_u *name = (char_u *)tv->vval.v_string;
int save_magic;
- char_u *save_cpo;
+ char *save_cpo;
buf_T *buf;
if (tv->v_type == VAR_NUMBER) {
@@ -776,9 +653,9 @@ buf_T *tv_get_buf(typval_T *tv, int curtab_only)
save_magic = p_magic;
p_magic = TRUE;
save_cpo = p_cpo;
- p_cpo = (char_u *)"";
+ p_cpo = "";
- buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
+ buf = buflist_findnr(buflist_findpat((char *)name, (char *)name + STRLEN(name),
true, false, curtab_only));
p_magic = save_magic;
@@ -819,9 +696,7 @@ buf_T *get_buf_arg(typval_T *arg)
return buf;
}
-/*
- * "byte2line(byte)" function
- */
+/// "byte2line(byte)" function
static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long boff = tv_get_number(&argvars[0]) - 1;
@@ -848,25 +723,21 @@ static void byteidx(typval_T *argvars, typval_T *rettv, int comp)
return;
}
if (comp) {
- t += utf_ptr2len((const char_u *)t);
+ t += utf_ptr2len(t);
} else {
- t += utfc_ptr2len((const char_u *)t);
+ t += utfc_ptr2len(t);
}
}
rettv->vval.v_number = (varnumber_T)(t - str);
}
-/*
- * "byteidx()" function
- */
+/// "byteidx()" function
static void f_byteidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
byteidx(argvars, rettv, FALSE);
}
-/*
- * "byteidxcomp()" function
- */
+/// "byteidxcomp()" function
static void f_byteidxcomp(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
byteidx(argvars, rettv, TRUE);
@@ -888,11 +759,12 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
partial_T *partial = NULL;
dict_T *selfdict = NULL;
if (argvars[0].v_type == VAR_FUNC) {
- func = argvars[0].vval.v_string;
+ func = (char_u *)argvars[0].vval.v_string;
} else if (argvars[0].v_type == VAR_PARTIAL) {
partial = argvars[0].vval.v_partial;
- func = partial_name(partial);
+ func = (char_u *)partial_name(partial);
} else if (nlua_is_table_from_lua(&argvars[0])) {
+ // TODO(tjdevries): UnifiedCallback
func = nlua_register_table_as_callable(&argvars[0]);
owned = true;
} else {
@@ -906,6 +778,9 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[2].v_type != VAR_UNKNOWN) {
if (argvars[2].v_type != VAR_DICT) {
emsg(_(e_dictreq));
+ if (owned) {
+ func_unref(func);
+ }
return;
}
selfdict = argvars[2].vval.v_dict;
@@ -917,15 +792,13 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "changenr()" function
- */
+/// "changenr()" function
static void f_changenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = curbuf->b_u_seq_cur;
}
-// "chanclose(id[, stream])" function
+/// "chanclose(id[, stream])" function
static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -943,7 +816,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ChannelPart part = kChannelPartAll;
if (argvars[1].v_type == VAR_STRING) {
- char *stream = (char *)argvars[1].vval.v_string;
+ char *stream = argvars[1].vval.v_string;
if (!strcmp(stream, "stdin")) {
part = kChannelPartStdin;
} else if (!strcmp(stream, "stdout")) {
@@ -964,7 +837,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "chansend(id, data)" function
+/// "chansend(id, data)" function
static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -1005,9 +878,7 @@ static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "char2nr(string)" function
- */
+/// "char2nr(string)" function
static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -1016,10 +887,54 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- rettv->vval.v_number = utf_ptr2char((const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = utf_ptr2char(tv_get_string(&argvars[0]));
}
-// "charidx()" function
+/// Get the current cursor column and store it in 'rettv'.
+///
+/// @return the character index of the column if 'charcol' is true,
+/// otherwise the byte index of the column.
+static void get_col(typval_T *argvars, typval_T *rettv, bool charcol)
+{
+ colnr_T col = 0;
+ pos_T *fp;
+ int fnum = curbuf->b_fnum;
+
+ fp = var2fpos(&argvars[0], false, &fnum, charcol);
+ if (fp != NULL && fnum == curbuf->b_fnum) {
+ 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;
+ } else {
+ col = MAXCOL;
+ }
+ } else {
+ col = fp->col + 1;
+ // 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();
+ if (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) {
+ col += l;
+ }
+ }
+ }
+ }
+ }
+ rettv->vval.v_number = col;
+}
+
+/// "charcol()" function
+static void f_charcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ get_col(argvars, rettv, true);
+}
+
+/// "charidx()" function
static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -1046,7 +961,7 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- int (*ptr2len)(const char_u *);
+ int (*ptr2len)(const char *);
if (countcc) {
ptr2len = utf_ptr2len;
} else {
@@ -1059,13 +974,13 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (*p == NUL) {
return;
}
- p += ptr2len((const char_u *)p);
+ p += ptr2len(p);
}
rettv->vval.v_number = len > 0 ? len - 1 : 0;
}
-// "chdir(dir)" function
+/// "chdir(dir)" function
static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *cwd;
@@ -1086,7 +1001,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(cwd);
#endif
- rettv->vval.v_string = vim_strsave(cwd);
+ rettv->vval.v_string = (char *)vim_strsave(cwd);
}
xfree(cwd);
@@ -1102,9 +1017,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "cindent(lnum)" function
- */
+/// "cindent(lnum)" function
static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T pos;
@@ -1121,7 +1034,7 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-static win_T *get_optional_window(typval_T *argvars, int idx)
+win_T *get_optional_window(typval_T *argvars, int idx)
{
win_T *win = curwin;
@@ -1135,65 +1048,16 @@ static win_T *get_optional_window(typval_T *argvars, int idx)
return win;
}
-/*
- * "clearmatches()" function
- */
-static void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- win_T *win = get_optional_window(argvars, 0);
-
- if (win != NULL) {
- clear_matches(win);
- }
-}
-
-/*
- * "col(string)" function
- */
+/// "col(string)" function
static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- colnr_T col = 0;
- pos_T *fp;
- int fnum = curbuf->b_fnum;
-
- fp = var2fpos(&argvars[0], FALSE, &fnum);
- if (fp != NULL && fnum == curbuf->b_fnum) {
- 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;
- } else {
- col = MAXCOL;
- }
- } else {
- col = fp->col + 1;
- // 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();
-
- if (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(p))] == NUL) {
- col += l;
- }
- }
- }
- }
- }
- rettv->vval.v_number = col;
+ get_col(argvars, rettv, false);
}
-/*
- * "complete()" function
- */
+/// "complete()" function
static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if ((State & INSERT) == 0) {
+ if ((State & MODE_INSERT) == 0) {
emsg(_("E785: complete() can only be used in Insert mode"));
return;
}
@@ -1206,28 +1070,21 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[1].v_type != VAR_LIST) {
emsg(_(e_invarg));
- return;
- }
-
- const colnr_T startcol = tv_get_number_chk(&argvars[0], NULL);
- if (startcol <= 0) {
- return;
+ } else {
+ const colnr_T startcol = tv_get_number_chk(&argvars[0], NULL);
+ if (startcol > 0) {
+ set_completion(startcol - 1, argvars[1].vval.v_list);
+ }
}
-
- set_completion(startcol - 1, argvars[1].vval.v_list);
}
-/*
- * "complete_add()" function
- */
+/// "complete_add()" function
static void f_complete_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0, false);
}
-/*
- * "complete_check()" function
- */
+/// "complete_check()" function
static void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int saved = RedrawingDisabled;
@@ -1238,7 +1095,7 @@ static void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr)
RedrawingDisabled = saved;
}
-// "complete_info()" function
+/// "complete_info()" function
static void f_complete_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
@@ -1255,9 +1112,7 @@ static void f_complete_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_complete_info(what_list, rettv->vval.v_dict);
}
-/*
- * "confirm(message, buttons[, default [, type]])" function
- */
+/// "confirm(message, buttons[, default [, type]])" function
static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
@@ -1312,17 +1167,13 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "copy()" function
- */
+/// "copy()" function
static void f_copy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
var_item_copy(NULL, &argvars[0], rettv, false, 0);
}
-/*
- * "count()" function
- */
+/// "count()" function
static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long n = 0;
@@ -1335,7 +1186,7 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[0].v_type == VAR_STRING) {
const char_u *expr = (char_u *)tv_get_string_chk(&argvars[1]);
- const char_u *p = argvars[0].vval.v_string;
+ const char_u *p = (char_u *)argvars[0].vval.v_string;
if (!error && expr != NULL && *expr != NUL && p != NULL) {
if (ic) {
@@ -1413,11 +1264,9 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
- *
- * Checks the existence of a cscope connection.
- */
+/// "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)
{
int num = 0;
@@ -1548,24 +1397,21 @@ static void f_ctxsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = ctx_size();
}
-/// "cursor(lnum, col)" function, or
-/// "cursor(list)"
-///
-/// Moves the cursor to the specified line and column.
-///
-/// @returns 0 when the position could be set, -1 otherwise.
-static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+/// Set the cursor position.
+/// If 'charcol' is true, then use the column number as a character offset.
+/// 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 coladd = 0;
bool set_curswant = true;
rettv->vval.v_number = -1;
- if (argvars[1].v_type == VAR_UNKNOWN) {
+ if (argvars[0].v_type == VAR_LIST) {
pos_T pos;
colnr_T curswant = -1;
- if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL) {
+ if (list2fpos(argvars, &pos, NULL, &curswant, charcol) == FAIL) {
emsg(_(e_invarg));
return;
}
@@ -1577,16 +1423,22 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
curwin->w_curswant = curswant - 1;
set_curswant = false;
}
- } else {
+ } 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);
col = (long)tv_get_number_chk(&argvars[1], NULL);
+ if (charcol) {
+ col = buf_charidx_to_byteidx(curbuf, line, col) + 1;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
coladd = (long)tv_get_number_chk(&argvars[2], NULL);
}
+ } else {
+ emsg(_(e_invarg));
+ return;
}
- if (line < 0 || col < 0
- || coladd < 0) {
- return; // type error; errmsg already given
+ if (line < 0 || col < 0 || coladd < 0) {
+ return; // type error; errmsg already given
}
if (line > 0) {
curwin->w_cursor.lnum = line;
@@ -1605,7 +1457,18 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 0;
}
-// "debugbreak()" function
+/// "cursor(lnum, col)" function, or
+/// "cursor(list)"
+///
+/// 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)
+{
+ set_cursorpos(argvars, rettv, false);
+}
+
+/// "debugbreak()" function
static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int pid;
@@ -1629,7 +1492,7 @@ static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "deepcopy()" function
+/// "deepcopy()" function
static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int noref = 0;
@@ -1646,7 +1509,7 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "delete()" function
+/// "delete()" function
static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -1682,7 +1545,7 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// dictwatcheradd(dict, key, funcref) function
+/// dictwatcheradd(dict, key, funcref) function
static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -1720,7 +1583,7 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
callback);
}
-// dictwatcherdel(dict, key, funcref) function
+/// dictwatcherdel(dict, key, funcref) function
static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -1768,6 +1631,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
const bool is_curbuf = buf == curbuf;
+ const bool save_VIsual_active = VIsual_active;
const linenr_T first = tv_get_lnum_buf(&argvars[1], buf);
if (argvars[2].v_type != VAR_UNKNOWN) {
@@ -1783,6 +1647,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (!is_curbuf) {
+ VIsual_active = false;
curbuf_save = curbuf;
curwin_save = curwin;
curbuf = buf;
@@ -1826,28 +1691,23 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!is_curbuf) {
curbuf = curbuf_save;
curwin = curwin_save;
+ VIsual_active = save_VIsual_active;
}
}
-/*
- * "did_filetype()" function
- */
+/// "did_filetype()" function
static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = did_filetype;
}
-/*
- * "diff_filler()" function
- */
+/// "diff_filler()" function
static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = MAX(0, diff_check(curwin, tv_get_lnum(argvars)));
}
-/*
- * "diff_hlID()" function
- */
+/// "diff_hlID()" function
static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = tv_get_lnum(argvars);
@@ -1899,9 +1759,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)(hlID + 1);
}
-/*
- * "empty({expr})" function
- */
+/// "empty({expr})" function
static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool n = true;
@@ -1998,15 +1856,14 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
os_free_fullenv(env);
}
-/*
- * "escape({string}, {chars})" function
- */
+/// "escape({string}, {chars})" function
static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
- rettv->vval.v_string = vim_strsave_escaped((const char_u *)tv_get_string(&argvars[0]),
- (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ rettv->vval.v_string = (char *)vim_strsave_escaped((const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1],
+ buf));
rettv->v_type = VAR_STRING;
}
@@ -2020,22 +1877,20 @@ static void f_getenv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_special = kSpecialVarNull;
return;
}
- rettv->vval.v_string = p;
+ rettv->vval.v_string = (char *)p;
rettv->v_type = VAR_STRING;
}
-/*
- * "eval()" function
- */
+/// "eval()" function
static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *s = tv_get_string_chk(&argvars[0]);
if (s != NULL) {
- s = (const char *)skipwhite((const char_u *)s);
+ s = (const char *)skipwhite(s);
}
const char *const expr_start = s;
- if (s == NULL || eval1((char_u **)&s, rettv, true) == FAIL) {
+ if (s == NULL || eval1((char **)&s, rettv, true) == FAIL) {
if (expr_start != NULL && !aborting()) {
semsg(_(e_invexpr2), expr_start);
}
@@ -2047,17 +1902,13 @@ static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "eventhandler()" function
- */
+/// "eventhandler()" function
static void f_eventhandler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = vgetc_busy;
}
-/*
- * "executable()" function
- */
+/// "executable()" function
static void f_executable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (tv_check_for_string(&argvars[0]) == FAIL) {
@@ -2073,7 +1924,7 @@ typedef struct {
const listitem_T *li;
} GetListLineCookie;
-static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
+static char *get_list_line(int c, void *cookie, int indent, bool do_concat)
{
GetListLineCookie *const p = (GetListLineCookie *)cookie;
@@ -2084,7 +1935,7 @@ static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
char buf[NUMBUFLEN];
const char *const s = tv_get_string_buf_chk(TV_LIST_ITEM_TV(item), buf);
p->li = TV_LIST_ITEM_NEXT(p->l, item);
- return (char_u *)(s == NULL ? NULL : xstrdup(s));
+ return s == NULL ? NULL : xstrdup(s);
}
static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int arg_off)
@@ -2165,36 +2016,24 @@ static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int
capture_ga = save_capture_ga;
}
-// "execute(command)" function
+/// "execute(command)" function
static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
execute_common(argvars, rettv, fptr, 0);
}
-// "win_execute(win_id, command)" function
+/// "win_execute(win_id, command)" function
static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- tabpage_T *tp;
- win_T *wp = win_id2wp_tp(argvars, &tp);
- win_T *save_curwin;
- tabpage_T *save_curtab;
// Return an empty string if something fails.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ int id = tv_get_number(argvars);
+ tabpage_T *tp;
+ win_T *wp = win_id2wp_tp(id, &tp);
if (wp != NULL && tp != NULL) {
- pos_T curpos = wp->w_cursor;
- if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, true) ==
- OK) {
- check_cursor();
- execute_common(argvars, rettv, fptr, 1);
- }
- restore_win_noblock(save_curwin, save_curtab, true);
-
- // Update the status line if the cursor moved.
- if (win_valid(wp) && !equalpos(curpos, wp->w_cursor)) {
- wp->w_redr_status = true;
- }
+ WIN_EXECUTE(wp, tp, execute_common(argvars, rettv, fptr, 1));
}
}
@@ -2209,13 +2048,17 @@ static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
(void)os_can_exe(tv_get_string(&argvars[0]), &path, true);
+#ifdef BACKSLASH_IN_FILENAME
+ if (path != NULL) {
+ slash_adjust((char_u *)path);
+ }
+#endif
+
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)path;
+ rettv->vval.v_string = path;
}
-/*
- * "exists()" function
- */
+/// "exists()" function
static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = false;
@@ -2227,7 +2070,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = true;
} else {
// Try expanding things like $VIM and ${HOME}.
- char_u *const exp = expand_env_save((char_u *)p);
+ char *const exp = expand_env_save((char *)p);
if (exp != NULL && *exp != '$') {
n = true;
}
@@ -2235,7 +2078,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else if (*p == '&' || *p == '+') { // Option.
n = (get_option_tv(&p, NULL, true) == OK);
- if (*skipwhite((const char_u *)p) != NUL) {
+ if (*skipwhite(p) != NUL) {
n = false; // Trailing garbage.
}
} else if (*p == '*') { // Internal or user defined function.
@@ -2255,9 +2098,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "expand()" function
- */
+/// "expand()" function
static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
size_t len;
@@ -2293,7 +2134,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
XFREE_CLEAR(result);
} else {
- rettv->vval.v_string = result;
+ rettv->vval.v_string = (char *)result;
}
} else {
// When the optional second argument is non-zero, don't remove matches
@@ -2309,8 +2150,8 @@ 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 = ExpandOne(&xpc, (char_u *)s, NULL, options,
- WILD_ALL);
+ rettv->vval.v_string = (char *)ExpandOne(&xpc, (char_u *)s, NULL, options,
+ WILD_ALL);
} else {
ExpandOne(&xpc, (char_u *)s, NULL, options, WILD_ALL_KEEP);
tv_list_alloc_ret(rettv, xpc.xp_numfiles);
@@ -2329,7 +2170,6 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#endif
}
-
/// "menu_get(path [, modes])" function
static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -2339,11 +2179,11 @@ static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *const strmodes = tv_get_string(&argvars[1]);
modes = get_menu_cmd_modes(strmodes, false, NULL, NULL);
}
- menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
+ menu_get((char *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
}
-// "expandcmd()" function
-// Expand all the special characters in a command string.
+/// "expandcmd()" function
+/// Expand all the special characters in a command string.
static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char *errormsg = NULL;
@@ -2352,8 +2192,8 @@ static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char_u *cmdstr = (char_u *)xstrdup(tv_get_string(&argvars[0]));
exarg_T eap = {
- .cmd = cmdstr,
- .arg = cmdstr,
+ .cmd = (char *)cmdstr,
+ .arg = (char *)cmdstr,
.usefilter = false,
.nextcmd = NULL,
.cmdidx = CMD_USER,
@@ -2364,10 +2204,9 @@ static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (errormsg != NULL && *errormsg != NUL) {
emsg(errormsg);
}
- rettv->vval.v_string = cmdstr;
+ rettv->vval.v_string = (char *)cmdstr;
}
-
/// "flatten(list[, {maxdepth}])" function
static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -2403,10 +2242,8 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "extend(list, list [, idx])" function
- * "extend(dict, dict [, action])" function
- */
+/// "extend(list, list [, idx])" function
+/// "extend(dict, dict [, action])" function
static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const arg_errmsg = N_("extend() argument");
@@ -2483,9 +2320,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "feedkeys()" function
- */
+/// "feedkeys()" function
static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
// This is not allowed in the sandbox. If the commands would still be
@@ -2514,17 +2349,15 @@ static void f_filereadable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
(*p && !os_isdir((const char_u *)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.
- */
+/// @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)
{
const char *filename = tv_get_string(&argvars[0]);
rettv->vval.v_number = os_file_is_writable(filename);
}
-
static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
{
char_u *fresult = NULL;
@@ -2566,7 +2399,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
fresult = find_file_in_path_option(first ? (char_u *)fname : NULL,
first ? strlen(fname) : 0,
0, first, path,
- find_what, curbuf->b_ffname,
+ find_what, (char_u *)curbuf->b_ffname,
(find_what == FINDFILE_DIR
? (char_u *)""
: curbuf->b_p_sua));
@@ -2579,44 +2412,35 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
}
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = fresult;
+ rettv->vval.v_string = (char *)fresult;
}
}
-
-/*
- * "filter()" function
- */
+/// "filter()" function
static void f_filter(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
filter_map(argvars, rettv, FALSE);
}
-/*
- * "finddir({fname}[, {path}[, {count}]])" function
- */
+/// "finddir({fname}[, {path}[, {count}]])" function
static void f_finddir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
findfilendir(argvars, rettv, FINDFILE_DIR);
}
-/*
- * "findfile({fname}[, {path}[, {count}]])" function
- */
+/// "findfile({fname}[, {path}[, {count}]])" function
static void f_findfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
findfilendir(argvars, rettv, FINDFILE_FILE);
}
-/*
- * "float2nr({float})" function
- */
+/// "float2nr({float})" function
static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
if (tv_get_float_chk(argvars, &f)) {
- if (f <= (float_T)-VARNUMBER_MAX + DBL_EPSILON) {
+ if (f <= (float_T) - VARNUMBER_MAX + DBL_EPSILON) {
rettv->vval.v_number = -VARNUMBER_MAX;
} else if (f >= (float_T)VARNUMBER_MAX - DBL_EPSILON) {
rettv->vval.v_number = VARNUMBER_MAX;
@@ -2626,9 +2450,7 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "fmod()" function
- */
+/// "fmod()" function
static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T fx;
@@ -2642,18 +2464,14 @@ static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "fnameescape({string})" function
- */
+/// "fnameescape({string})" function
static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(tv_get_string(&argvars[0]), false);
+ rettv->vval.v_string = vim_strsave_fnameescape(tv_get_string(&argvars[0]), VSE_NONE);
rettv->v_type = VAR_STRING;
}
-/*
- * "fnamemodify({fname}, {mods})" function
- */
+/// "fnamemodify({fname}, {mods})" function
static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *fbuf = NULL;
@@ -2667,8 +2485,8 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
len = strlen(fname);
if (*mods != NUL) {
size_t usedlen = 0;
- (void)modify_fname((char_u *)mods, false, &usedlen,
- (char_u **)&fname, &fbuf, &len);
+ (void)modify_fname((char *)mods, false, &usedlen,
+ (char **)&fname, (char **)&fbuf, &len);
}
}
@@ -2676,15 +2494,12 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (fname == NULL) {
rettv->vval.v_string = NULL;
} else {
- rettv->vval.v_string = (char_u *)xmemdupz(fname, len);
+ rettv->vval.v_string = xmemdupz(fname, len);
}
xfree(fbuf);
}
-
-/*
- * "foldclosed()" function
- */
+/// "foldclosed()" function
static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -2703,25 +2518,19 @@ static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
rettv->vval.v_number = -1;
}
-/*
- * "foldclosed()" function
- */
+/// "foldclosed()" function
static void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, FALSE);
}
-/*
- * "foldclosedend()" function
- */
+/// "foldclosedend()" function
static void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, TRUE);
}
-/*
- * "foldlevel()" function
- */
+/// "foldlevel()" function
static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -2730,9 +2539,7 @@ static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "foldtext()" function
- */
+/// "foldtext()" function
static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T foldstart;
@@ -2749,7 +2556,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART);
foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
- dashes = get_vim_var_str(VV_FOLDDASHES);
+ dashes = (char_u *)get_vim_var_str(VV_FOLDDASHES);
if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) {
// Find first non-empty line in the fold.
for (lnum = foldstart; lnum < foldend; lnum++) {
@@ -2759,18 +2566,18 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// Find interesting text in this line.
- s = skipwhite(ml_get(lnum));
+ s = (char_u *)skipwhite((char *)ml_get(lnum));
// skip C comment-start
if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) {
- s = skipwhite(s + 2);
- if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
- s = skipwhite(ml_get(lnum + 1));
+ s = (char_u *)skipwhite((char *)s + 2);
+ if (*skipwhite((char *)s) == NUL && lnum + 1 < foldend) {
+ s = (char_u *)skipwhite((char *)ml_get(lnum + 1));
if (*s == '*') {
- s = skipwhite(s + 1);
+ s = (char_u *)skipwhite((char *)s + 1);
}
}
}
- unsigned long count = (unsigned long)(foldend - foldstart + 1);
+ unsigned long count = (unsigned long)foldend - foldstart + 1;
txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
r = xmalloc(STRLEN(txt)
+ STRLEN(dashes) // for %s
@@ -2781,13 +2588,11 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
STRCAT(r, s);
// remove 'foldmarker' and 'commentstring'
foldtext_cleanup(r + len);
- rettv->vval.v_string = r;
+ rettv->vval.v_string = (char *)r;
}
}
-/*
- * "foldtextresult(lnum)" function
- */
+/// "foldtextresult(lnum)" function
static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *text;
@@ -2812,18 +2617,15 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (text == buf) {
text = vim_strsave(text);
}
- rettv->vval.v_string = text;
+ rettv->vval.v_string = (char *)text;
}
entered = false;
}
-/*
- * "foreground()" function
- */
+/// "foreground()" function
static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
-}
+{}
static void f_funcref(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -2847,9 +2649,7 @@ static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "get()" function
- */
+/// "get()" function
static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
listitem_T *li;
@@ -2899,7 +2699,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
pt = argvars[0].vval.v_partial;
} else {
memset(&fref_pt, 0, sizeof(fref_pt));
- fref_pt.pt_name = argvars[0].vval.v_string;
+ fref_pt.pt_name = (char_u *)argvars[0].vval.v_string;
pt = &fref_pt;
}
@@ -2910,9 +2710,9 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING);
const char *const n = (const char *)partial_name(pt);
assert(n != NULL);
- rettv->vval.v_string = (char_u *)xstrdup(n);
+ rettv->vval.v_string = xstrdup(n);
if (rettv->v_type == VAR_FUNC) {
- func_ref(rettv->vval.v_string);
+ func_ref((char_u *)rettv->vval.v_string);
}
} else if (strcmp(what, "dict") == 0) {
what_is_dict = true;
@@ -3009,12 +2809,12 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * Get line or list of lines from buffer "buf" into "rettv".
- * Return a range (from start to end) of lines in rettv from the specified
- * buffer.
- * If 'retlist' is TRUE, then the lines are returned as a Vim List.
- */
+/// Get line or list of lines from buffer "buf" into "rettv".
+///
+/// @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.
static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)
{
rettv->v_type = (retlist ? VAR_LIST : VAR_STRING);
@@ -3041,15 +2841,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 = ((start >= 1 && start <= buf->b_ml.ml_line_count)
- ? vim_strsave(ml_get_buf(buf, start, false))
- : NULL);
+ rettv->vval.v_string =
+ (char *)((start >= 1 && start <= buf->b_ml.ml_line_count)
+ ? vim_strsave(ml_get_buf(buf, start, false)) : NULL);
}
}
-/*
- * "getbufline()" function
- */
+/// "getbufline()" function
static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *const buf = tv_get_buf_from_arg(&argvars[0]);
@@ -3062,9 +2860,7 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_buffer_lines(buf, lnum, end, true, rettv);
}
-/*
- * "getbufvar()" function
- */
+/// "getbufvar()" function
static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool done = false;
@@ -3124,7 +2920,7 @@ f_getbufvar_end:
}
}
-// "getchangelist()" function
+/// "getchangelist()" function
static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
@@ -3164,7 +2960,7 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "getchar()" and "getcharstr()" functions
+/// "getchar()" and "getcharstr()" functions
static void getchar_common(typval_T *argvars, typval_T *rettv)
FUNC_ATTR_NONNULL_ALL
{
@@ -3172,6 +2968,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
bool error = false;
no_mapping++;
+ allow_keys++;
for (;;) {
// Position the cursor. Needed after a message that ends in a space,
// or if event processing caused a redraw.
@@ -3180,7 +2977,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
if (argvars[0].v_type == VAR_UNKNOWN) {
// getchar(): blocking wait.
// TODO(bfredl): deduplicate shared logic with state_enter ?
- if (!(char_avail() || using_script() || input_available())) {
+ if (!char_avail()) {
(void)os_inchar(NULL, 0, -1, 0, main_loop.events);
if (!multiqueue_empty(main_loop.events)) {
state_handle_k_event();
@@ -3209,6 +3006,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
break;
}
no_mapping--;
+ allow_keys--;
set_vim_var_nr(VV_MOUSE_WIN, 0);
set_vim_var_nr(VV_MOUSE_WINID, 0);
@@ -3216,7 +3014,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
set_vim_var_nr(VV_MOUSE_COL, 0);
rettv->vval.v_number = n;
- if (IS_SPECIAL(n) || mod_mask != 0) {
+ if (n != 0 && (IS_SPECIAL(n) || mod_mask != 0)) {
char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1
int i = 0;
@@ -3231,12 +3029,12 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
temp[i++] = K_SECOND(n);
temp[i++] = K_THIRD(n);
} else {
- i += utf_char2bytes(n, temp + i);
+ i += utf_char2bytes(n, (char *)temp + i);
}
assert(i < 10);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(temp);
+ rettv->vval.v_string = (char *)vim_strsave(temp);
if (is_mouse_key(n)) {
int row = mouse_row;
@@ -3266,43 +3064,100 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
}
}
-// "getchar()" function
+/// "getchar()" function
static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getchar_common(argvars, rettv);
}
-// "getcharstr()" function
+/// "getcharstr()" function
static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getchar_common(argvars, rettv);
if (rettv->v_type == VAR_NUMBER) {
- char_u temp[7]; // mbyte-char: 6, NUL: 1
+ char temp[7]; // mbyte-char: 6, NUL: 1
const varnumber_T n = rettv->vval.v_number;
int i = 0;
if (n != 0) {
- i += utf_char2bytes(n, temp);
+ i += utf_char2bytes(n, (char *)temp);
}
assert(i < 7);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(temp);
+ rettv->vval.v_string = xstrdup(temp);
}
}
-/*
- * "getcharmod()" function
- */
+/// "getcharmod()" function
static void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = mod_mask;
}
-/*
- * "getcharsearch()" function
- */
+static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos, bool charcol)
+{
+ pos_T *fp = NULL;
+ pos_T pos;
+ win_T *wp = curwin;
+ int fnum = -1;
+
+ if (getcurpos) {
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp != NULL) {
+ fp = &wp->w_cursor;
+ }
+ } else {
+ fp = &curwin->w_cursor;
+ }
+ if (fp != NULL && charcol) {
+ pos = *fp;
+ pos.col = buf_byteidx_to_charidx(wp->w_buffer, pos.lnum, pos.col);
+ fp = &pos;
+ }
+ } else {
+ fp = var2fpos(&argvars[0], true, &fnum, charcol);
+ }
+
+ list_T *const l = tv_list_alloc_ret(rettv, 4 + getcurpos);
+ tv_list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
+ tv_list_append_number(l, ((fp != NULL) ? (varnumber_T)fp->lnum : (varnumber_T)0));
+ tv_list_append_number(l, ((fp != NULL)
+ ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
+ : (varnumber_T)0));
+ tv_list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
+ if (getcurpos) {
+ const int save_set_curswant = curwin->w_set_curswant;
+ const colnr_T save_curswant = curwin->w_curswant;
+ const colnr_T save_virtcol = curwin->w_virtcol;
+
+ if (wp == curwin) {
+ update_curswant();
+ }
+ tv_list_append_number(l, (wp == NULL) ? 0 : ((wp->w_curswant == MAXCOL)
+ ? (varnumber_T)MAXCOL
+ : (varnumber_T)wp->w_curswant + 1));
+
+ // Do not change "curswant", as it is unexpected that a get
+ // function has a side effect.
+ if (wp == curwin && save_set_curswant) {
+ curwin->w_set_curswant = save_set_curswant;
+ curwin->w_curswant = save_curswant;
+ curwin->w_virtcol = save_virtcol;
+ curwin->w_valid &= ~VALID_VIRTCOL;
+ }
+ }
+}
+
+/// "getcharpos()" function
+static void f_getcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ getpos_both(argvars, rettv, false, true);
+}
+
+/// "getcharsearch()" function
static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
@@ -3314,26 +3169,33 @@ static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(dict, S_LEN("until"), last_csearch_until());
}
-/*
- * "getcmdline()" function
- */
+/// "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 = get_cmdline_str();
+ rettv->vval.v_string = (char *)get_cmdline_str();
}
-/*
- * "getcmdpos()" function
- */
+/// "getcmdpos()" function
static void f_getcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = get_cmdline_pos() + 1;
}
-/*
- * "getcmdtype()" function
- */
+/// "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;
@@ -3341,9 +3203,7 @@ static void f_getcmdtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string[0] = get_cmdline_type();
}
-/*
- * "getcmdwintype()" function
- */
+/// "getcmdwintype()" function
static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -3352,7 +3212,7 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string[0] = cmdwin_type;
}
-// "getcompletion()" function
+/// "getcompletion()" function
static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *pat;
@@ -3394,7 +3254,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
ExpandInit(&xpc);
- xpc.xp_pattern = (char_u *)pattern;
+ xpc.xp_pattern = (char *)pattern;
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
xpc.xp_context = cmdcomplete_str_to_type(type);
if (xpc.xp_context == EXPAND_NOTHING) {
@@ -3413,12 +3273,12 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (xpc.xp_context == EXPAND_SIGN) {
- set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
+ set_context_in_sign_cmd(&xpc, (char_u *)xpc.xp_pattern);
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
}
theend:
- pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
+ pat = addstar((char_u *)xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
ExpandOne(&xpc, pat, NULL, options, WILD_ALL_KEEP);
tv_list_alloc_ret(rettv, xpc.xp_numfiles);
@@ -3451,8 +3311,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
[kCdScopeTabpage] = 0, // Number of tab to look at.
};
- char_u *cwd = NULL; // Current working directory to print
- char_u *from = NULL; // The original string to copy
+ char *cwd = NULL; // Current working directory to print
+ char *from = NULL; // The original string to copy
tabpage_T *tp = curtab; // The tabpage to look at.
win_T *win = curwin; // The window to look at.
@@ -3534,8 +3394,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
FALLTHROUGH; // In global directory, just need to get OS CWD.
case kCdScopeInvalid: // If called without any arguments, get OS CWD.
- if (os_dirname(cwd, MAXPATHL) == FAIL) {
- from = (char_u *)""; // Return empty string on failure.
+ if (os_dirname((char_u *)cwd, MAXPATHL) == FAIL) {
+ from = ""; // Return empty string on failure.
}
}
@@ -3543,7 +3403,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
STRLCPY(cwd, from, MAXPATHL);
}
- rettv->vval.v_string = vim_strsave(cwd);
+ rettv->vval.v_string = xstrdup(cwd);
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(rettv->vval.v_string);
#endif
@@ -3551,18 +3411,14 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(cwd);
}
-/*
- * "getfontname()" function
- */
+/// "getfontname()" function
static void f_getfontname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
}
-/*
- * "getfperm({fname})" function
- */
+/// "getfperm({fname})" function
static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char *perm = NULL;
@@ -3579,12 +3435,10 @@ static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)perm;
+ rettv->vval.v_string = perm;
}
-/*
- * "getfsize({fname})" function
- */
+/// "getfsize({fname})" function
static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *fname = tv_get_string(&argvars[0]);
@@ -3609,9 +3463,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "getftime({fname})" function
- */
+/// "getftime({fname})" function
static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *fname = tv_get_string(&argvars[0]);
@@ -3624,9 +3476,7 @@ static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "getftype({fname})" function
- */
+/// "getftype({fname})" function
static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *type = NULL;
@@ -3657,10 +3507,10 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
type = vim_strsave((char_u *)t);
}
- rettv->vval.v_string = type;
+ rettv->vval.v_string = (char *)type;
}
-// "getjumplist()" function
+/// "getjumplist()" function
static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, kListLenMayKnow);
@@ -3686,14 +3536,12 @@ static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(d, S_LEN("coladd"), wp->w_jumplist[i].fmark.mark.coladd);
tv_dict_add_nr(d, S_LEN("bufnr"), wp->w_jumplist[i].fmark.fnum);
if (wp->w_jumplist[i].fname != NULL) {
- tv_dict_add_str(d, S_LEN("filename"), (char *)wp->w_jumplist[i].fname);
+ tv_dict_add_str(d, S_LEN("filename"), wp->w_jumplist[i].fname);
}
}
}
-/*
- * "getline(lnum, [end])" function
- */
+/// "getline(lnum, [end])" function
static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T end;
@@ -3718,7 +3566,6 @@ static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_qf_loc_list(false, wp, &argvars[1], rettv);
}
-
/// "getmarklist()" function
static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -3737,65 +3584,8 @@ static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_buf_local_marks(buf, rettv->vval.v_list);
}
-/*
- * "getmatches()" function
- */
-static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- matchitem_T *cur;
- int i;
- win_T *win = get_optional_window(argvars, 0);
-
- if (win == NULL) {
- return;
- }
-
- tv_list_alloc_ret(rettv, kListLenMayKnow);
- cur = win->w_match_head;
- while (cur != NULL) {
- dict_T *dict = tv_dict_alloc();
- if (cur->match.regprog == NULL) {
- // match added with matchaddpos()
- for (i = 0; i < MAXPOSMATCH; i++) {
- llpos_T *llpos;
- char buf[30]; // use 30 to avoid compiler warning
-
- llpos = &cur->pos.pos[i];
- if (llpos->lnum == 0) {
- break;
- }
- list_T *const l = tv_list_alloc(1 + (llpos->col > 0 ? 2 : 0));
- tv_list_append_number(l, (varnumber_T)llpos->lnum);
- if (llpos->col > 0) {
- tv_list_append_number(l, (varnumber_T)llpos->col);
- tv_list_append_number(l, (varnumber_T)llpos->len);
- }
- int len = snprintf(buf, sizeof(buf), "pos%d", i + 1);
- assert((size_t)len < sizeof(buf));
- tv_dict_add_list(dict, buf, (size_t)len, l);
- }
- } else {
- tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cur->pattern);
- }
- tv_dict_add_str(dict, S_LEN("group"),
- (const char *)syn_id2name(cur->hlg_id));
- tv_dict_add_nr(dict, S_LEN("priority"), (varnumber_T)cur->priority);
- tv_dict_add_nr(dict, S_LEN("id"), (varnumber_T)cur->id);
-
- if (cur->conceal_char) {
- char buf[MB_MAXBYTES + 1];
-
- buf[utf_char2bytes(cur->conceal_char, (char_u *)buf)] = NUL;
- tv_dict_add_str(dict, S_LEN("conceal"), buf);
- }
-
- tv_list_append_dict(rettv->vval.v_list, dict);
- cur = cur->next;
- }
-}
-
-// "getmousepos()" function
-void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+/// "getmousepos()" function
+static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *d;
win_T *wp;
@@ -3805,7 +3595,7 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
varnumber_T winid = 0;
varnumber_T winrow = 0;
varnumber_T wincol = 0;
- linenr_T line = 0;
+ linenr_T lnum = 0;
varnumber_T column = 0;
tv_dict_alloc_ret(rettv);
@@ -3816,26 +3606,16 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
wp = mouse_find_win(&grid, &row, &col);
if (wp != NULL) {
- int height = wp->w_height + wp->w_status_height;
+ int height = wp->w_height + wp->w_hsep_height + wp->w_status_height;
// The height is adjusted by 1 when there is a bottom border. This is not
// necessary for a top border since `row` starts at -1 in that case.
if (row < height + wp->w_border_adj[2]) {
winid = wp->handle;
- winrow = row + 1 + wp->w_border_adj[0]; // Adjust by 1 for top border
- wincol = col + 1 + wp->w_border_adj[3]; // Adjust by 1 for left border
+ winrow = row + 1 + wp->w_winrow_off; // Adjust by 1 for top border
+ wincol = col + 1 + wp->w_wincol_off; // Adjust by 1 for left border
if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) {
- char_u *p;
- int count;
-
- mouse_comp_pos(wp, &row, &col, &line);
-
- // limit to text length plus one
- p = ml_get_buf(wp->w_buffer, line, false);
- count = (int)STRLEN(p);
- if (col > count) {
- col = count;
- }
-
+ (void)mouse_comp_pos(wp, &row, &col, &lnum);
+ col = vcol2col(wp, lnum, col);
column = col + 1;
}
}
@@ -3843,73 +3623,31 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(d, S_LEN("winid"), winid);
tv_dict_add_nr(d, S_LEN("winrow"), winrow);
tv_dict_add_nr(d, S_LEN("wincol"), wincol);
- tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)line);
+ tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)lnum);
tv_dict_add_nr(d, S_LEN("column"), column);
}
-/*
- * "getpid()" function
- */
+/// "getpid()" function
static void f_getpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = os_get_pid();
}
-static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos)
+/// "getcurpos(string)" function
+static void f_getcurpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T *fp;
- int fnum = -1;
-
- if (getcurpos) {
- fp = &curwin->w_cursor;
- } else {
- fp = var2fpos(&argvars[0], true, &fnum);
- }
-
- list_T *const l = tv_list_alloc_ret(rettv, 4 + (!!getcurpos));
- tv_list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
- tv_list_append_number(l, ((fp != NULL)
- ? (varnumber_T)fp->lnum
- : (varnumber_T)0));
- tv_list_append_number(l, ((fp != NULL)
- ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
- : (varnumber_T)0));
- tv_list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
- if (getcurpos) {
- const int save_set_curswant = curwin->w_set_curswant;
- const colnr_T save_curswant = curwin->w_curswant;
- const colnr_T save_virtcol = curwin->w_virtcol;
-
- update_curswant();
- tv_list_append_number(l, (curwin->w_curswant == MAXCOL
- ? (varnumber_T)MAXCOL
- : (varnumber_T)curwin->w_curswant + 1));
-
- // Do not change "curswant", as it is unexpected that a get
- // function has a side effect.
- if (save_set_curswant) {
- curwin->w_set_curswant = save_set_curswant;
- curwin->w_curswant = save_curswant;
- curwin->w_virtcol = save_virtcol;
- curwin->w_valid &= ~VALID_VIRTCOL;
- }
- }
+ getpos_both(argvars, rettv, true, false);
}
-/*
- * "getcurpos(string)" function
- */
-static void f_getcurpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static void f_getcursorcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- getpos_both(argvars, rettv, true);
+ getpos_both(argvars, rettv, true, true);
}
-/*
- * "getpos(string)" function
- */
+/// "getpos(string)" function
static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- getpos_both(argvars, rettv, false);
+ getpos_both(argvars, rettv, false, false);
}
/// "getqflist()" functions
@@ -3932,7 +3670,7 @@ static int getreg_get_regname(typval_T *argvars)
}
} else {
// Default to v:register
- strregname = get_vim_var_str(VV_REG);
+ strregname = (char_u *)get_vim_var_str(VV_REG);
}
return *strregname == 0 ? '"' : *strregname;
@@ -3991,7 +3729,7 @@ static void f_getregtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
MotionType reg_type = get_reg_type(regname, &reglen);
format_reg_type(reg_type, reglen, buf, ARRAY_SIZE(buf));
- rettv->vval.v_string = (char_u *)xstrdup(buf);
+ rettv->vval.v_string = xstrdup(buf);
}
/// "gettabinfo()" function
@@ -4026,13 +3764,9 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "gettabvar()" function
- */
+/// "gettabvar()" function
static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *oldcurwin;
- tabpage_T *oldtabpage;
bool done = false;
rettv->v_type = VAR_STRING;
@@ -4046,7 +3780,8 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
win_T *const window = tp == curtab || tp->tp_firstwin == NULL
? firstwin
: tp->tp_firstwin;
- if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
+ switchwin_T switchwin;
+ if (switch_win(&switchwin, window, tp, true) == OK) {
// look up the variable
// Let gettabvar({nr}, "") return the "t:" dictionary.
const dictitem_T *const v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
@@ -4059,7 +3794,7 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// restore previous notion of curwin
- restore_win(oldcurwin, oldtabpage, true);
+ restore_win(&switchwin, true);
}
if (!done && argvars[2].v_type != VAR_UNKNOWN) {
@@ -4067,15 +3802,13 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "gettabwinvar()" function
- */
+/// "gettabwinvar()" function
static void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getwinvar(argvars, rettv, 1);
}
-// "gettagstack()" function
+/// "gettagstack()" function
static void f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp = curwin; // default is current window
@@ -4100,7 +3833,7 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_alloc_ret(rettv, kListLenMayKnow);
if (argvars[0].v_type != VAR_UNKNOWN) {
- wparg = win_id2wp(argvars);
+ wparg = win_id2wp(tv_get_number(&argvars[0]));
if (wparg == NULL) {
return;
}
@@ -4127,12 +3860,11 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// Dummy timer callback. Used by f_wait().
+/// Dummy timer callback. Used by f_wait().
static void dummy_timer_due_cb(TimeWatcher *tw, void *data)
-{
-}
+{}
-// Dummy timer close callback. Used by f_wait().
+/// Dummy timer close callback. Used by f_wait().
static void dummy_timer_close_cb(TimeWatcher *tw, void *data)
{
xfree(tw);
@@ -4170,15 +3902,14 @@ static void f_wait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
typval_T argv = TV_INITIAL_VALUE;
typval_T exprval = TV_INITIAL_VALUE;
bool error = false;
- int save_called_emsg = called_emsg;
- called_emsg = false;
+ const int called_emsg_before = called_emsg;
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, timeout,
eval_expr_typval(&expr, &argv, 0, &exprval) != OK
|| tv_get_number_chk(&exprval, &error)
- || called_emsg || error || got_int);
+ || called_emsg > called_emsg_before || error || got_int);
- if (called_emsg || error) {
+ if (called_emsg > called_emsg_before || error) {
rettv->vval.v_number = -3;
} else if (got_int) {
got_int = false;
@@ -4188,14 +3919,12 @@ static void f_wait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 0;
}
- called_emsg = save_called_emsg;
-
// Stop dummy timer
time_watcher_stop(tw);
time_watcher_close(tw, dummy_timer_close_cb);
}
-// "win_screenpos()" function
+/// "win_screenpos()" function
static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
@@ -4204,16 +3933,14 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
}
-//
-// Move the window wp into a new split of targetwin in a given direction
-//
+/// Move the window wp into a new split of targetwin in a given direction
static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags)
{
int dir;
int height = wp->w_height;
win_T *oldwin = curwin;
- if (wp == targetwin) {
+ if (wp == targetwin || wp == aucmd_win) {
return;
}
@@ -4244,7 +3971,7 @@ static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags
}
}
-// "win_splitmove()" function
+/// "win_splitmove()" function
static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp;
@@ -4284,7 +4011,7 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
win_move_into_split(wp, targetwin, size, flags);
}
-// "getwinpos({timeout})" function
+/// "getwinpos({timeout})" function
static void f_getwinpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
@@ -4292,17 +4019,13 @@ static void f_getwinpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, -1);
}
-/*
- * "getwinposx()" function
- */
+/// "getwinposx()" function
static void f_getwinposx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
}
-/*
- * "getwinposy()" function
- */
+/// "getwinposy()" function
static void f_getwinposy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -4314,9 +4037,7 @@ static void f_getwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
getwinvar(argvars, rettv, 0);
}
-/*
- * "glob()" function
- */
+/// "glob()" function
static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int options = WILD_SILENT|WILD_USE_NL;
@@ -4347,8 +4068,9 @@ 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 = ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
- WILD_ALL);
+ rettv->vval.v_string = (char *)ExpandOne(&xpc, (char_u *)
+ tv_get_string(&argvars[0]), NULL, options,
+ WILD_ALL);
} else {
ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
WILD_ALL_KEEP);
@@ -4399,7 +4121,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags);
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = (char_u *)ga_concat_strings_sep(&ga, "\n");
+ rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n");
} else {
tv_list_alloc_ret(rettv, ga.ga_len);
for (int i = 0; i < ga.ga_len; i++) {
@@ -4414,16 +4136,13 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "glob2regpat()" function
+/// "glob2regpat()" function
static void f_glob2regpat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const pat = tv_get_string_chk(&argvars[0]); // NULL on type error
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = ((pat == NULL)
- ? NULL
- : file_pat_to_reg_pat((char_u *)pat, NULL, NULL,
- false));
+ rettv->vval.v_string = (pat == NULL) ? NULL : file_pat_to_reg_pat(pat, NULL, NULL, false);
}
/// "has()" function
@@ -4433,6 +4152,12 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#if defined(BSD) && !defined(__APPLE__)
"bsd",
#endif
+#ifdef __linux__
+ "linux",
+#endif
+#ifdef SUN_SYSTEM
+ "sun",
+#endif
#ifdef UNIX
"unix",
#endif
@@ -4504,6 +4229,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"mouse",
"multi_byte",
"multi_lang",
+ "nanotime",
"num64",
"packages",
"path_extra",
@@ -4555,6 +4281,8 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"userreg",
};
+ // XXX: eval_has_provider() may shell out :(
+ const int save_shell_error = get_vim_var_nr(VV_SHELL_ERROR);
bool n = false;
const char *const name = tv_get_string(&argvars[0]);
for (size_t i = 0; i < ARRAY_SIZE(has_list); i++) {
@@ -4611,6 +4339,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = true;
}
+ set_vim_var_nr(VV_SHELL_ERROR, save_shell_error);
rettv->vval.v_number = n;
}
@@ -4746,34 +4475,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "hasmapto()" function
- */
-static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *mode;
- const char *const name = tv_get_string(&argvars[0]);
- bool abbr = false;
- char buf[NUMBUFLEN];
- if (argvars[1].v_type == VAR_UNKNOWN) {
- mode = "nvo";
- } else {
- mode = tv_get_string_buf(&argvars[1], buf);
- if (argvars[2].v_type != VAR_UNKNOWN) {
- abbr = tv_get_number(&argvars[2]);
- }
- }
-
- if (map_to_exists(name, mode, abbr)) {
- rettv->vval.v_number = true;
- } else {
- rettv->vval.v_number = false;
- }
-}
-
-/*
- * "histadd()" function
- */
+/// "histadd()" function
static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType histype;
@@ -4796,9 +4498,7 @@ static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "histdel()" function
- */
+/// "histdel()" function
static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n;
@@ -4821,9 +4521,7 @@ static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "histget()" function
- */
+/// "histget()" function
static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType type;
@@ -4840,14 +4538,12 @@ static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
idx = (int)tv_get_number_chk(&argvars[1], NULL);
}
// -1 on type error
- rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
+ rettv->vval.v_string = (char *)vim_strsave(get_history_entry(type, idx));
}
rettv->v_type = VAR_STRING;
}
-/*
- * "histnr()" function
- */
+/// "histnr()" function
static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const history = tv_get_string_chk(&argvars[0]);
@@ -4860,37 +4556,29 @@ static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = i;
}
-/*
- * "highlightID(name)" function
- */
+/// "highlightID(name)" function
static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = syn_name2id(tv_get_string(&argvars[0]));
}
-/*
- * "highlight_exists()" function
- */
+/// "highlight_exists()" function
static void f_hlexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = highlight_exists(tv_get_string(&argvars[0]));
}
-/*
- * "hostname()" function
- */
+/// "hostname()" function
static void f_hostname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char hostname[256];
os_get_hostname(hostname, 256);
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave((char_u *)hostname);
+ rettv->vval.v_string = (char *)vim_strsave((char_u *)hostname);
}
-/*
- * iconv() function
- */
+/// iconv() function
static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
vimconv_T vimconv;
@@ -4908,9 +4596,9 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// If the encodings are equal, no conversion needed.
if (vimconv.vc_type == CONV_NONE) {
- rettv->vval.v_string = (char_u *)xstrdup(str);
+ rettv->vval.v_string = xstrdup(str);
} else {
- rettv->vval.v_string = string_convert(&vimconv, (char_u *)str, NULL);
+ rettv->vval.v_string = (char *)string_convert(&vimconv, (char_u *)str, NULL);
}
convert_setup(&vimconv, NULL, NULL);
@@ -4918,9 +4606,7 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(to);
}
-/*
- * "indent()" function
- */
+/// "indent()" function
static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -4931,9 +4617,7 @@ static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "index()" function
- */
+/// "index()" function
static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long idx = 0;
@@ -5007,26 +4691,20 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static bool inputsecret_flag = false;
-/*
- * "input()" function
- * Also handles inputsecret() when inputsecret is set.
- */
+/// "input()" function
+/// Also handles inputsecret() when inputsecret is set.
static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_user_input(argvars, rettv, FALSE, inputsecret_flag);
}
-/*
- * "inputdialog()" function
- */
+/// "inputdialog()" function
static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_user_input(argvars, rettv, TRUE, inputsecret_flag);
}
-/*
- * "inputlist()" function
- */
+/// "inputlist()" function
static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int selected;
@@ -5057,7 +4735,6 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = selected;
}
-
static garray_T ga_userinput = { 0, 0, sizeof(tasave_T), 4, NULL };
/// "inputrestore()" function
@@ -5092,9 +4769,7 @@ static void f_inputsecret(typval_T *argvars, typval_T *rettv, FunPtr fptr)
inputsecret_flag = false;
}
-/*
- * "insert()" function
- */
+/// "insert()" function
static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
list_T *l;
@@ -5166,43 +4841,37 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "interrupt()" function
+/// "interrupt()" function
static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED, typval_T *rettv FUNC_ATTR_UNUSED,
FunPtr fptr FUNC_ATTR_UNUSED)
{
got_int = true;
}
-/*
- * "invert(expr)" function
- */
+/// "invert(expr)" function
static void f_invert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ~tv_get_number_chk(&argvars[0], NULL);
}
-/*
- * "isdirectory()" function
- */
+/// "isdirectory()" function
static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = os_isdir((const char_u *)tv_get_string(&argvars[0]));
}
-/*
- * "islocked()" function
- */
+/// "islocked()" function
static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
lval_T lv;
dictitem_T *di;
rettv->vval.v_number = -1;
- const char_u *const end = get_lval((char_u *)tv_get_string(&argvars[0]),
- NULL,
- &lv, false, false,
- GLV_NO_AUTOLOAD|GLV_READ_ONLY,
- FNE_CHECK_START);
+ const char_u *const end = (char_u *)get_lval((char *)tv_get_string(&argvars[0]),
+ NULL,
+ &lv, false, false,
+ GLV_NO_AUTOLOAD|GLV_READ_ONLY,
+ FNE_CHECK_START);
if (end != NULL && lv.ll_name != NULL) {
if (*end != NUL) {
emsg(_(e_trailing));
@@ -5234,7 +4903,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
clear_lval(&lv);
}
-// "isinf()" function
+/// "isinf()" function
static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type == VAR_FLOAT
@@ -5243,7 +4912,7 @@ static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "isnan()" function
+/// "isnan()" function
static void f_isnan(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
@@ -5257,19 +4926,16 @@ static void f_id(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const int len = vim_vsnprintf_typval(NULL, 0, "%p", dummy_ap, argvars);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = xmalloc(len + 1);
- vim_vsnprintf_typval((char *)rettv->vval.v_string, len + 1, "%p",
- dummy_ap, argvars);
+ vim_vsnprintf_typval(rettv->vval.v_string, len + 1, "%p", dummy_ap, argvars);
}
-/*
- * "items(dict)" function
- */
+/// "items(dict)" function
static void f_items(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 2);
}
-// "jobpid(id)" function
+/// "jobpid(id)" function
static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5293,7 +4959,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = proc->pid;
}
-// "jobresize(job, width, height)" function
+/// "jobresize(job, width, height)" function
static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5310,7 +4976,6 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-
Channel *data = find_job(argvars[0].vval.v_number, true);
if (!data) {
return;
@@ -5402,6 +5067,16 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
tv_dict_add_str(env, S_LEN("TERM"), pty_term_name);
}
+ // Set $NVIM (in the child process) to v:servername. #3118
+ char *nvim_addr = get_vim_var_str(VV_SEND_SERVER);
+ if (nvim_addr[0] != '\0') {
+ dictitem_T *dv = tv_dict_find(env, S_LEN("NVIM"));
+ if (dv) {
+ tv_dict_item_remove(env, dv);
+ }
+ tv_dict_add_str(env, S_LEN("NVIM"), nvim_addr);
+ }
+
if (job_env) {
#ifdef WIN32
TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, {
@@ -5440,7 +5115,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
return env;
}
-// "jobstart()" function
+/// "jobstart()" function
static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5465,7 +5140,6 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-
dict_T *job_opts = NULL;
bool detach = false;
bool rpc = false;
@@ -5561,7 +5235,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "jobstop()" function
+/// "jobstop()" function
static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5594,7 +5268,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "jobwait(ids[, timeout])" function
+/// "jobwait(ids[, timeout])" function
static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5693,9 +5367,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_list = rv;
}
-/*
- * "join()" function
- */
+/// "join()" function
static void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type != VAR_LIST) {
@@ -5713,7 +5385,7 @@ static void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ga_init(&ga, (int)sizeof(char), 80);
tv_list_join(&ga, argvars[0].vval.v_list, sep);
ga_append(&ga, NUL);
- rettv->vval.v_string = (char_u *)ga.ga_data;
+ rettv->vval.v_string = ga.ga_data;
} else {
rettv->vval.v_string = NULL;
}
@@ -5757,20 +5429,16 @@ static void f_json_decode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_json_encode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)encode_tv2json(&argvars[0], NULL);
+ rettv->vval.v_string = encode_tv2json(&argvars[0], NULL);
}
-/*
- * "keys()" function
- */
+/// "keys()" function
static void f_keys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 0);
}
-/*
- * "last_buffer_nr()" function.
- */
+/// "last_buffer_nr()" function.
static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = 0;
@@ -5784,9 +5452,7 @@ static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "len()" function
- */
+/// "len()" function
static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
switch (argvars[0].v_type) {
@@ -5830,19 +5496,17 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
return;
}
- const char *libname = (char *)argvars[0].vval.v_string;
- const char *funcname = (char *)argvars[1].vval.v_string;
+ const char *libname = argvars[0].vval.v_string;
+ const char *funcname = argvars[1].vval.v_string;
VarType in_type = argvars[2].v_type;
// input variables
- char *str_in = (in_type == VAR_STRING)
- ? (char *)argvars[2].vval.v_string : NULL;
+ char *str_in = (in_type == VAR_STRING) ? argvars[2].vval.v_string : NULL;
int int_in = argvars[2].vval.v_number;
// output variables
- char **str_out = (out_type == VAR_STRING)
- ? (char **)&rettv->vval.v_string : NULL;
+ char **str_out = (out_type == VAR_STRING) ? &rettv->vval.v_string : NULL;
int int_out = 0;
bool success = os_libcall(libname, funcname,
@@ -5859,23 +5523,19 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
}
}
-/*
- * "libcall()" function
- */
+/// "libcall()" function
static void f_libcall(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
libcall_common(argvars, rettv, VAR_STRING);
}
-/*
- * "libcallnr()" function
- */
+/// "libcallnr()" function
static void f_libcallnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
libcall_common(argvars, rettv, VAR_NUMBER);
}
-// "line(string, [winid])" function
+/// "line(string, [winid])" function
static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = 0;
@@ -5883,23 +5543,21 @@ static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int fnum;
if (argvars[1].v_type != VAR_UNKNOWN) {
- tabpage_T *tp;
- win_T *save_curwin;
- tabpage_T *save_curtab;
-
// use window specified in the second argument
- win_T *wp = win_id2wp_tp(&argvars[1], &tp);
+ int id = (int)tv_get_number(&argvars[1]);
+ tabpage_T *tp;
+ win_T *wp = win_id2wp_tp(id, &tp);
if (wp != NULL && tp != NULL) {
- if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, true)
- == OK) {
+ switchwin_T switchwin;
+ if (switch_win_noblock(&switchwin, wp, tp, true) == OK) {
check_cursor();
- fp = var2fpos(&argvars[0], true, &fnum);
+ fp = var2fpos(&argvars[0], true, &fnum, false);
}
- restore_win_noblock(save_curwin, save_curtab, true);
+ restore_win_noblock(&switchwin, true);
}
} else {
// use current window
- fp = var2fpos(&argvars[0], true, &fnum);
+ fp = var2fpos(&argvars[0], true, &fnum, false);
}
if (fp != NULL) {
@@ -5908,9 +5566,7 @@ static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = lnum;
}
-/*
- * "line2byte(lnum)" function
- */
+/// "line2byte(lnum)" function
static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -5924,9 +5580,7 @@ static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "lispindent(lnum)" function
- */
+/// "lispindent(lnum)" function
static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const pos_T pos = curwin->w_cursor;
@@ -5940,7 +5594,7 @@ static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "list2str()" function
+/// "list2str()" function
static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
garray_T ga;
@@ -5958,10 +5612,10 @@ static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
ga_init(&ga, 1, 80);
- char_u buf[MB_MAXBYTES + 1];
+ char buf[MB_MAXBYTES + 1];
TV_LIST_ITER_CONST(l, li, {
- buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), buf)] = NUL;
+ buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), (char *)buf)] = NUL;
ga_concat(&ga, (char *)buf);
});
ga_append(&ga, NUL);
@@ -5969,82 +5623,12 @@ static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = ga.ga_data;
}
-/*
- * "localtime()" function
- */
+/// "localtime()" function
static void f_localtime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (varnumber_T)time(NULL);
}
-
-static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
-{
- char_u *keys_buf = NULL;
- char_u *rhs;
- LuaRef rhs_lua;
- int mode;
- int abbr = FALSE;
- int get_dict = FALSE;
- mapblock_T *mp;
- int buffer_local;
-
- // Return empty string for failure.
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = NULL;
-
- char_u *keys = (char_u *)tv_get_string(&argvars[0]);
- if (*keys == NUL) {
- return;
- }
-
- char buf[NUMBUFLEN];
- const char *which;
- if (argvars[1].v_type != VAR_UNKNOWN) {
- which = tv_get_string_buf_chk(&argvars[1], buf);
- if (argvars[2].v_type != VAR_UNKNOWN) {
- abbr = tv_get_number(&argvars[2]);
- if (argvars[3].v_type != VAR_UNKNOWN) {
- get_dict = tv_get_number(&argvars[3]);
- }
- }
- } else {
- which = "";
- }
- if (which == NULL) {
- return;
- }
-
- mode = get_map_mode((char_u **)&which, 0);
-
- keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
- CPO_TO_CPO_FLAGS);
- rhs = check_map(keys, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua);
- xfree(keys_buf);
-
- if (!get_dict) {
- // Return a string.
- if (rhs != NULL) {
- if (*rhs == NUL) {
- rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
- } else {
- rettv->vval.v_string = (char_u *)str2special_save((char *)rhs, false, false);
- }
- } else if (rhs_lua != LUA_NOREF) {
- size_t msglen = 100;
- char *msg = (char *)xmalloc(msglen);
- snprintf(msg, msglen, "<Lua function %d>", mp->m_luaref);
- rettv->vval.v_string = (char_u *)msg;
- }
- } else {
- tv_dict_alloc_ret(rettv);
- if (mp != NULL && (rhs != NULL || rhs_lua != LUA_NOREF)) {
- // Return a dictionary.
- mapblock_fill_dict(rettv->vval.v_dict, mp, buffer_local, true);
- }
- }
-}
-
/// luaeval() function implementation
static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
@@ -6057,31 +5641,12 @@ static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
nlua_typval_eval(cstr_as_string((char *)str), &argvars[1], rettv);
}
-/*
- * "map()" function
- */
+/// "map()" function
static void f_map(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
filter_map(argvars, rettv, TRUE);
}
-/*
- * "maparg()" function
- */
-static void f_maparg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- get_maparg(argvars, rettv, TRUE);
-}
-
-/*
- * "mapcheck()" function
- */
-static void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- get_maparg(argvars, rettv, FALSE);
-}
-
-
static void find_some_match(typval_T *const argvars, typval_T *const rettv,
const SomeMatchType type)
{
@@ -6089,7 +5654,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
long len = 0;
char_u *expr = NULL;
regmatch_T regmatch;
- char_u *save_cpo;
+ char *save_cpo;
long start = 0;
long nth = 1;
colnr_T startcol = 0;
@@ -6101,7 +5666,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.
save_cpo = p_cpo;
- p_cpo = (char_u *)"";
+ p_cpo = "";
rettv->vval.v_number = -1;
switch (type) {
@@ -6182,7 +5747,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
}
}
- regmatch.regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING);
+ regmatch.regprog = vim_regcomp((char *)pat, RE_MAGIC + RE_STRING);
if (regmatch.regprog != NULL) {
regmatch.rm_ic = p_ic;
@@ -6215,7 +5780,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
idx++;
} else {
startcol = (colnr_T)(regmatch.startp[0]
- + utfc_ptr2len(regmatch.startp[0]) - str);
+ + utfc_ptr2len((char *)regmatch.startp[0]) - str);
if (startcol > (colnr_T)len || str + startcol <= regmatch.startp[0]) {
match = false;
break;
@@ -6261,9 +5826,9 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
if (l != NULL) {
tv_copy(TV_LIST_ITEM_TV(li), rettv);
} else {
- rettv->vval.v_string = (char_u *)xmemdupz((const char *)regmatch.startp[0],
- (size_t)(regmatch.endp[0] -
- regmatch.startp[0]));
+ rettv->vval.v_string = xmemdupz((const char *)regmatch.startp[0],
+ (size_t)(regmatch.endp[0] -
+ regmatch.startp[0]));
}
break;
case kSomeMatch:
@@ -6297,166 +5862,25 @@ theend:
p_cpo = save_cpo;
}
-/*
- * "match()" function
- */
+/// "match()" function
static void f_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatch);
}
-/*
- * "matchadd()" function
- */
-static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- char grpbuf[NUMBUFLEN];
- char patbuf[NUMBUFLEN];
- // group
- const char *const grp = tv_get_string_buf_chk(&argvars[0], grpbuf);
- // pattern
- const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
- // default priority
- int prio = 10;
- int id = -1;
- bool error = false;
- const char *conceal_char = NULL;
- win_T *win = curwin;
-
- rettv->vval.v_number = -1;
-
- if (grp == NULL || pat == NULL) {
- return;
- }
- if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = tv_get_number_chk(&argvars[2], &error);
- if (argvars[3].v_type != VAR_UNKNOWN) {
- id = tv_get_number_chk(&argvars[3], &error);
- if (argvars[4].v_type != VAR_UNKNOWN
- && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL) {
- return;
- }
- }
- }
- if (error) {
- return;
- }
- if (id >= 1 && id <= 3) {
- semsg(_("E798: ID is reserved for \":match\": %" PRId64), (int64_t)id);
- return;
- }
-
- rettv->vval.v_number = match_add(win, grp, pat, prio, id, NULL, conceal_char);
-}
-
-static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = -1;
-
- char buf[NUMBUFLEN];
- const char *const group = tv_get_string_buf_chk(&argvars[0], buf);
- if (group == NULL) {
- return;
- }
-
- if (argvars[1].v_type != VAR_LIST) {
- semsg(_(e_listarg), "matchaddpos()");
- return;
- }
-
- list_T *l;
- l = argvars[1].vval.v_list;
- if (l == NULL) {
- return;
- }
-
- bool error = false;
- int prio = 10;
- int id = -1;
- const char *conceal_char = NULL;
- win_T *win = curwin;
-
- if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = tv_get_number_chk(&argvars[2], &error);
- if (argvars[3].v_type != VAR_UNKNOWN) {
- id = tv_get_number_chk(&argvars[3], &error);
- if (argvars[4].v_type != VAR_UNKNOWN
- && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL) {
- return;
- }
- }
- }
- if (error == true) {
- return;
- }
-
- // id == 3 is ok because matchaddpos() is supposed to substitute :3match
- if (id == 1 || id == 2) {
- semsg(_("E798: ID is reserved for \"match\": %" PRId64), (int64_t)id);
- return;
- }
-
- rettv->vval.v_number = match_add(win, group, NULL, prio, id, l, conceal_char);
-}
-
-/*
- * "matcharg()" function
- */
-static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const int id = tv_get_number(&argvars[0]);
-
- tv_list_alloc_ret(rettv, (id >= 1 && id <= 3
- ? 2
- : 0));
-
- if (id >= 1 && id <= 3) {
- matchitem_T *const m = get_match(curwin, id);
-
- if (m != NULL) {
- tv_list_append_string(rettv->vval.v_list,
- (const char *)syn_id2name(m->hlg_id), -1);
- tv_list_append_string(rettv->vval.v_list, (const char *)m->pattern, -1);
- } else {
- tv_list_append_string(rettv->vval.v_list, NULL, 0);
- tv_list_append_string(rettv->vval.v_list, NULL, 0);
- }
- }
-}
-
-/*
- * "matchdelete()" function
- */
-static void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- win_T *win = get_optional_window(argvars, 1);
- if (win == NULL) {
- rettv->vval.v_number = -1;
- } else {
- rettv->vval.v_number = match_delete(win,
- (int)tv_get_number(&argvars[0]), true);
- }
-}
-
-/*
- * "matchend()" function
- */
+/// "matchend()" function
static void f_matchend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatchEnd);
}
-/*
- * "matchlist()" function
- */
+/// "matchlist()" function
static void f_matchlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatchList);
}
-/*
- * "matchstr()" function
- */
+/// "matchstr()" function
static void f_matchstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatchStr);
@@ -6517,25 +5941,19 @@ static void max_min(const typval_T *const tv, typval_T *const rettv, const bool
rettv->vval.v_number = n;
}
-/*
- * "max()" function
- */
+/// "max()" function
static void f_max(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
max_min(argvars, rettv, TRUE);
}
-/*
- * "min()" function
- */
+/// "min()" function
static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
max_min(argvars, rettv, FALSE);
}
-/*
- * "mkdir()" function
- */
+/// "mkdir()" function
static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int prot = 0755; // -V536
@@ -6551,9 +5969,9 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- if (*path_tail((char_u *)dir) == NUL) {
+ if (*path_tail(dir) == NUL) {
// Remove trailing slashes.
- *path_tail_with_sep((char_u *)dir) = NUL;
+ *path_tail_with_sep((char *)dir) = NUL;
}
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -6583,15 +6001,17 @@ 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)
{
- char *mode = get_mode();
+ char buf[MODE_MAX_LENGTH];
+
+ get_mode(buf);
// Clear out the minor mode when the argument is not a non-zero number or
// non-empty string.
if (!non_zero_arg(&argvars[0])) {
- mode[1] = NUL;
+ buf[1] = NUL;
}
- rettv->vval.v_string = (char_u *)mode;
+ rettv->vval.v_string = xstrdup(buf);
rettv->v_type = VAR_STRING;
}
@@ -6750,9 +6170,7 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "nextnonblank()" function
- */
+/// "nextnonblank()" function
static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum;
@@ -6762,16 +6180,14 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
lnum = 0;
break;
}
- if (*skipwhite(ml_get(lnum)) != NUL) {
+ if (*skipwhite((char *)ml_get(lnum)) != NUL) {
break;
}
}
rettv->vval.v_number = lnum;
}
-/*
- * "nr2char()" function
- */
+/// "nr2char()" function
static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -6796,37 +6212,42 @@ static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
char buf[MB_MAXBYTES];
- const int len = utf_char2bytes((int)num, (char_u *)buf);
+ const int len = utf_char2bytes((int)num, buf);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = xmemdupz(buf, (size_t)len);
}
-/*
- * "or(expr, expr)" function
- */
+/// "or(expr, expr)" function
static void f_or(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
| tv_get_number_chk(&argvars[1], NULL);
}
-/*
- * "pathshorten()" function
- */
+/// "pathshorten()" function
static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
+ int trim_len = 1;
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ trim_len = (int)tv_get_number(&argvars[1]);
+ if (trim_len < 1) {
+ trim_len = 1;
+ }
+ }
+
rettv->v_type = VAR_STRING;
- const char *const s = tv_get_string_chk(&argvars[0]);
- if (!s) {
- return;
+ const char_u *p = (char_u *)tv_get_string_chk(&argvars[0]);
+ if (p == NULL) {
+ rettv->vval.v_string = NULL;
+ } else {
+ rettv->vval.v_string = (char *)vim_strsave(p);
+ shorten_dir_len((char_u *)rettv->vval.v_string, trim_len);
}
- rettv->vval.v_string = shorten_dir((char_u *)xstrdup(s));
}
-/*
- * "pow()" function
- */
+/// "pow()" function
static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T fx;
@@ -6840,25 +6261,21 @@ static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "prevnonblank()" function
- */
+/// "prevnonblank()" function
static void f_prevnonblank(typval_T *argvars, typval_T *rettv, FunPtr 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(ml_get(lnum)) == NUL) {
+ while (lnum >= 1 && *skipwhite((char *)ml_get(lnum)) == NUL) {
lnum--;
}
}
rettv->vval.v_number = lnum;
}
-/*
- * "printf()" function
- */
+/// "printf()" function
static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -6874,14 +6291,14 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
len = vim_vsnprintf_typval(NULL, 0, fmt, dummy_ap, argvars + 1);
if (!did_emsg) {
char *s = xmalloc(len + 1);
- rettv->vval.v_string = (char_u *)s;
+ rettv->vval.v_string = s;
(void)vim_vsnprintf_typval(s, len + 1, fmt, dummy_ap, argvars + 1);
}
did_emsg |= saved_did_emsg;
}
}
-// "prompt_setcallback({buffer}, {callback})" function
+/// "prompt_setcallback({buffer}, {callback})" function
static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -6905,7 +6322,7 @@ static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr
buf->b_prompt_callback = prompt_callback;
}
-// "prompt_setinterrupt({buffer}, {callback})" function
+/// "prompt_setinterrupt({buffer}, {callback})" function
static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -6930,7 +6347,7 @@ static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fpt
}
/// "prompt_getprompt({buffer})" function
-void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
// return an empty string by default, e.g. it's not a prompt buffer
@@ -6946,38 +6363,33 @@ void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- rettv->vval.v_string = vim_strsave(buf_prompt_text(buf));
+ rettv->vval.v_string = (char *)vim_strsave(buf_prompt_text(buf));
}
-// "prompt_setprompt({buffer}, {text})" function
+/// "prompt_setprompt({buffer}, {text})" function
static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- const char_u *text;
-
if (check_secure()) {
return;
}
- buf = tv_get_buf(&argvars[0], false);
+ buf_T *buf = tv_get_buf(&argvars[0], false);
if (buf == NULL) {
return;
}
- text = (const char_u *)tv_get_string(&argvars[1]);
+ const char *text = tv_get_string(&argvars[1]);
xfree(buf->b_prompt_text);
- buf->b_prompt_text = vim_strsave(text);
+ buf->b_prompt_text = xstrdup(text);
}
-// "pum_getpos()" function
+/// "pum_getpos()" function
static void f_pum_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
pum_set_event_info(rettv->vval.v_dict);
}
-/*
- * "pumvisible()" function
- */
+/// "pumvisible()" function
static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (pum_visible()) {
@@ -6985,50 +6397,183 @@ static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "pyeval()" function
- */
-static void f_pyeval(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)
{
- script_host_eval("python", argvars, rettv);
+ script_host_eval("python3", argvars, rettv);
}
-/*
- * "py3eval()" function
- */
-static void f_py3eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static void init_srand(uint32_t *const x)
+ FUNC_ATTR_NONNULL_ALL
{
- script_host_eval("python3", argvars, rettv);
+#ifndef MSWIN
+ static int dev_urandom_state = NOTDONE; // FAIL or OK once tried
+
+ if (dev_urandom_state != FAIL) {
+ const int fd = os_open("/dev/urandom", O_RDONLY, 0);
+ struct {
+ union {
+ uint32_t number;
+ char bytes[sizeof(uint32_t)];
+ } contents;
+ } buf;
+
+ // Attempt reading /dev/urandom.
+ if (fd == -1) {
+ dev_urandom_state = FAIL;
+ } else {
+ buf.contents.number = 0;
+ if (read(fd, buf.contents.bytes, sizeof(uint32_t)) != sizeof(uint32_t)) {
+ dev_urandom_state = FAIL;
+ } else {
+ dev_urandom_state = OK;
+ *x = buf.contents.number;
+ }
+ os_close(fd);
+ }
+ }
+ if (dev_urandom_state != OK) {
+ // Reading /dev/urandom doesn't work, fall back to time().
+#endif
+ // uncrustify:off
+ *x = time(NULL);
+#ifndef MSWIN
+ }
+#endif
+ // uncrustify:on
}
-// "pyxeval()" function
-static void f_pyxeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static inline uint32_t splitmix32(uint32_t *const x)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
- init_pyxversion();
- if (p_pyx == 2) {
- f_pyeval(argvars, rettv, NULL);
+ uint32_t z = (*x += 0x9e3779b9);
+ z = (z ^ (z >> 16)) * 0x85ebca6b;
+ z = (z ^ (z >> 13)) * 0xc2b2ae35;
+ return z ^ (z >> 16);
+}
+
+static inline uint32_t shuffle_xoshiro128starstar(uint32_t *const x, uint32_t *const y,
+ uint32_t *const z, uint32_t *const w)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
+{
+#define ROTL(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+ const uint32_t result = ROTL(*y * 5, 7) * 9;
+ const uint32_t t = *y << 9;
+ *z ^= *x;
+ *w ^= *y;
+ *y ^= *z;
+ *x ^= *w;
+ *z ^= t;
+ *w = ROTL(*w, 11);
+#undef ROTL
+ return result;
+}
+
+/// "rand()" function
+static void f_rand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ uint32_t result;
+
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ static uint32_t gx, gy, gz, gw;
+ static bool initialized = false;
+
+ // When no argument is given use the global seed list.
+ if (!initialized) {
+ // Initialize the global seed list.
+ uint32_t x;
+ init_srand(&x);
+
+ gx = splitmix32(&x);
+ gy = splitmix32(&x);
+ gz = splitmix32(&x);
+ gw = splitmix32(&x);
+ initialized = true;
+ }
+
+ result = shuffle_xoshiro128starstar(&gx, &gy, &gz, &gw);
+ } else if (argvars[0].v_type == VAR_LIST) {
+ list_T *const l = argvars[0].vval.v_list;
+ if (tv_list_len(l) != 4) {
+ goto theend;
+ }
+
+ typval_T *const tvx = TV_LIST_ITEM_TV(tv_list_find(l, 0L));
+ typval_T *const tvy = TV_LIST_ITEM_TV(tv_list_find(l, 1L));
+ typval_T *const tvz = TV_LIST_ITEM_TV(tv_list_find(l, 2L));
+ typval_T *const tvw = TV_LIST_ITEM_TV(tv_list_find(l, 3L));
+ if (tvx->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ if (tvy->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ if (tvz->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ if (tvw->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ uint32_t x = tvx->vval.v_number;
+ uint32_t y = tvy->vval.v_number;
+ uint32_t z = tvz->vval.v_number;
+ uint32_t w = tvw->vval.v_number;
+
+ result = shuffle_xoshiro128starstar(&x, &y, &z, &w);
+
+ tvx->vval.v_number = (varnumber_T)x;
+ tvy->vval.v_number = (varnumber_T)y;
+ tvz->vval.v_number = (varnumber_T)z;
+ tvw->vval.v_number = (varnumber_T)w;
} else {
- f_py3eval(argvars, rettv, NULL);
+ goto theend;
}
+
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = (varnumber_T)result;
+ return;
+
+theend:
+ semsg(_(e_invarg2), tv_get_string(&argvars[0]));
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = -1;
+}
+
+/// "srand()" function
+static void f_srand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ uint32_t x = 0;
+
+ tv_list_alloc_ret(rettv, 4);
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ init_srand(&x);
+ } else {
+ bool error = false;
+ x = tv_get_number_chk(&argvars[0], &error);
+ if (error) {
+ return;
+ }
+ }
+
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
}
-///
/// "perleval()" function
-///
static void f_perleval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
script_host_eval("perl", argvars, rettv);
}
-// "rubyeval()" function
+/// "rubyeval()" function
static void f_rubyeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
script_host_eval("ruby", argvars, rettv);
}
-/*
- * "range()" function
- */
+/// "range()" function
static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
varnumber_T start;
@@ -7063,19 +6608,25 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// Evaluate "expr" for readdir().
-static varnumber_T readdir_checkitem(typval_T *expr, const char *name)
+/// Evaluate "expr" (= "context") for readdir().
+static varnumber_T readdir_checkitem(void *context, const char *name)
+ FUNC_ATTR_NONNULL_ALL
{
+ typval_T *expr = (typval_T *)context;
typval_T save_val;
typval_T rettv;
typval_T argv[2];
varnumber_T retval = 0;
bool error = false;
+ if (expr->v_type == VAR_UNKNOWN) {
+ return 1;
+ }
+
prepare_vimvar(VV_VAL, &save_val);
set_vim_var_string(VV_VAL, name, -1);
argv[0].v_type = VAR_STRING;
- argv[0].vval.v_string = (char_u *)name;
+ argv[0].vval.v_string = (char *)name;
if (eval_expr_typval(expr, argv, 1, &rettv) == FAIL) {
goto theend;
@@ -7094,65 +6645,25 @@ theend:
return retval;
}
-// "readdir()" function
+/// "readdir()" function
static void f_readdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- typval_T *expr;
- const char *path;
- garray_T ga;
- Directory dir;
-
tv_list_alloc_ret(rettv, kListLenUnknown);
- path = tv_get_string(&argvars[0]);
- expr = &argvars[1];
- ga_init(&ga, (int)sizeof(char *), 20);
- if (!os_scandir(&dir, path)) {
- smsg(_(e_notopen), path);
- } else {
- for (;;) {
- bool ignore;
-
- path = os_scandir_next(&dir);
- if (path == NULL) {
- break;
- }
-
- ignore = (path[0] == '.'
- && (path[1] == NUL || (path[1] == '.' && path[2] == NUL)));
- if (!ignore && expr->v_type != VAR_UNKNOWN) {
- varnumber_T r = readdir_checkitem(expr, path);
-
- if (r < 0) {
- break;
- }
- if (r == 0) {
- ignore = true;
- }
- }
-
- if (!ignore) {
- ga_grow(&ga, 1);
- ((char **)ga.ga_data)[ga.ga_len++] = xstrdup(path);
- }
- }
-
- os_closedir(&dir);
- }
-
- if (rettv->vval.v_list != NULL && ga.ga_len > 0) {
- sort_strings((char_u **)ga.ga_data, ga.ga_len);
+ const char *path = tv_get_string(&argvars[0]);
+ typval_T *expr = &argvars[1];
+ garray_T ga;
+ int ret = readdir_core(&ga, path, (void *)expr, readdir_checkitem);
+ if (ret == OK && ga.ga_len > 0) {
for (int i = 0; i < ga.ga_len; i++) {
- path = ((const char **)ga.ga_data)[i];
- tv_list_append_string(rettv->vval.v_list, path, -1);
+ const char *p = ((const char **)ga.ga_data)[i];
+ tv_list_append_string(rettv->vval.v_list, p, -1);
}
}
ga_clear_strings(&ga);
}
-/*
- * "readfile()" function
- */
+/// "readfile()" function
static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool binary = false;
@@ -7250,7 +6761,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 = s,
+ .vval.v_string = (char *)s,
});
start = p + 1; // Step over newline.
@@ -7386,13 +6897,13 @@ static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "reg_executing()" function
+/// "reg_executing()" function
static void f_reg_executing(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
return_register(reg_executing, rettv);
}
-// "reg_recording()" function
+/// "reg_recording()" function
static void f_reg_recording(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
return_register(reg_recording, rettv);
@@ -7490,13 +7001,11 @@ static void f_reltimestr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (list2proftime(&argvars[0], &tm) == OK) {
- rettv->vval.v_string = (char_u *)xstrdup(profile_msg(tm));
+ rettv->vval.v_string = xstrdup(profile_msg(tm));
}
}
-/*
- * "remove()" function
- */
+/// "remove()" function
static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
list_T *l;
@@ -7630,9 +7139,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "rename({from}, {to})" function
- */
+/// "rename({from}, {to})" function
static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -7644,9 +7151,7 @@ static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "repeat()" function
- */
+/// "repeat()" function
static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
varnumber_T n = tv_get_number(&argvars[1]);
@@ -7679,13 +7184,11 @@ static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
memmove(r + i * slen, p, slen);
}
- rettv->vval.v_string = (char_u *)r;
+ rettv->vval.v_string = r;
}
}
-/*
- * "resolve()" function
- */
+/// "resolve()" function
static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -7765,11 +7268,11 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
q[-1] = NUL;
}
- q = (char *)path_tail((char_u *)p);
+ q = path_tail(p);
if (q > p && *q == NUL) {
// Ignore trailing path separator.
q[-1] = NUL;
- q = (char *)path_tail((char_u *)p);
+ q = path_tail(p);
}
if (q > p && !path_is_absolute((const char_u *)buf)) {
// Symlink is relative to directory of argument. Replace the
@@ -7777,7 +7280,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const size_t p_len = strlen(p);
const size_t buf_len = strlen(buf);
p = xrealloc(p, p_len + buf_len + 1);
- memcpy(path_tail((char_u *)p), buf, buf_len + 1);
+ memcpy(path_tail(p), buf, buf_len + 1);
} else {
xfree(p);
p = xstrdup(buf);
@@ -7838,11 +7341,11 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!has_trailing_pathsep) {
q = p + strlen(p);
if (after_pathsep(p, q)) {
- *path_tail_with_sep((char_u *)p) = NUL;
+ *path_tail_with_sep(p) = NUL;
}
}
- rettv->vval.v_string = (char_u *)p;
+ rettv->vval.v_string = p;
xfree(buf);
}
# else
@@ -7851,12 +7354,10 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
# endif
#endif
- simplify_filename(rettv->vval.v_string);
+ simplify_filename((char_u *)rettv->vval.v_string);
}
-/*
- * "reverse({list})" function
- */
+/// "reverse({list})" function
static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type == VAR_BLOB) {
@@ -7881,6 +7382,102 @@ 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)
+{
+ if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) {
+ emsg(_(e_listblobreq));
+ return;
+ }
+
+ const char *func_name;
+ partial_T *partial = NULL;
+ if (argvars[1].v_type == VAR_FUNC) {
+ func_name = argvars[1].vval.v_string;
+ } else if (argvars[1].v_type == VAR_PARTIAL) {
+ partial = argvars[1].vval.v_partial;
+ func_name = partial_name(partial);
+ } else {
+ func_name = tv_get_string(&argvars[1]);
+ }
+ if (*func_name == NUL) {
+ return; // type error or empty name
+ }
+
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.evaluate = true;
+ funcexe.partial = partial;
+
+ typval_T initial;
+ typval_T argv[3];
+ if (argvars[0].v_type == VAR_LIST) {
+ list_T *const l = argvars[0].vval.v_list;
+ const listitem_T *li;
+
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ if (tv_list_len(l) == 0) {
+ semsg(_(e_reduceempty), "List");
+ return;
+ }
+ const listitem_T *const first = tv_list_first(l);
+ initial = *TV_LIST_ITEM_TV(first);
+ li = TV_LIST_ITEM_NEXT(l, first);
+ } else {
+ initial = argvars[2];
+ li = tv_list_first(l);
+ }
+
+ tv_copy(&initial, rettv);
+
+ if (l != NULL) {
+ const VarLockStatus prev_locked = tv_list_locked(l);
+ const int called_emsg_start = called_emsg;
+
+ tv_list_set_lock(l, VAR_FIXED); // disallow the list changing here
+ for (; li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) {
+ argv[0] = *rettv;
+ argv[1] = *TV_LIST_ITEM_TV(li);
+ rettv->v_type = VAR_UNKNOWN;
+ const int r = call_func((char *)func_name, -1, rettv, 2, argv, &funcexe);
+ tv_clear(&argv[0]);
+ if (r == FAIL || called_emsg != called_emsg_start) {
+ break;
+ }
+ }
+ tv_list_set_lock(l, prev_locked);
+ }
+ } else {
+ const blob_T *const b = argvars[0].vval.v_blob;
+ int i;
+
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ if (tv_blob_len(b) == 0) {
+ semsg(_(e_reduceempty), "Blob");
+ return;
+ }
+ initial.v_type = VAR_NUMBER;
+ initial.vval.v_number = tv_blob_get(b, 0);
+ i = 1;
+ } else if (argvars[2].v_type != VAR_NUMBER) {
+ emsg(_(e_number_exp));
+ return;
+ } else {
+ initial = argvars[2];
+ i = 0;
+ }
+
+ tv_copy(&initial, rettv);
+ for (; i < tv_blob_len(b); i++) {
+ argv[0] = *rettv;
+ argv[1].v_type = VAR_NUMBER;
+ argv[1].vval.v_number = tv_blob_get(b, i);
+ if (call_func((char *)func_name, -1, rettv, 2, argv, &funcexe) == FAIL) {
+ return;
+ }
+ }
+ }
+}
+
#define SP_NOMOVE 0x01 ///< don't move cursor
#define SP_REPEAT 0x02 ///< repeat to find outer pair
#define SP_RETCOUNT 0x04 ///< return matchcount
@@ -7890,11 +7487,10 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#define SP_END 0x40 ///< leave cursor at end of match
#define SP_COLUMN 0x80 ///< start at cursor column
-/*
- * Get flags for a search function.
- * Possibly sets "p_ws".
- * Returns BACKWARD, FORWARD or zero (for an error).
- */
+/// Get flags for a search function.
+/// Possibly sets "p_ws".
+///
+/// @return BACKWARD, FORWARD or zero (for an error).
static int get_search_arg(typval_T *varp, int *flagsp)
{
int dir = FORWARD;
@@ -7952,7 +7548,7 @@ static int get_search_arg(typval_T *varp, int *flagsp)
return dir;
}
-// Shared by search() and searchpos() functions.
+/// Shared by search() and searchpos() functions.
static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
{
int flags;
@@ -7967,6 +7563,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
int options = SEARCH_KEEP;
int subpatnum;
searchit_arg_T sia;
+ bool use_skip = false;
const char *const pat = tv_get_string(&argvars[0]);
dir = get_search_arg(&argvars[1], flagsp); // May set p_ws.
@@ -7984,7 +7581,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
options |= SEARCH_COL;
}
- // Optional arguments: line number to stop searching and timeout.
+ // Optional arguments: line number to stop searching, timeout and skip.
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[2], NULL);
if (lnum_stop < 0) {
@@ -7995,6 +7592,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
if (time_limit < 0) {
goto theend;
}
+ use_skip = eval_expr_valid_arg(&argvars[4]);
}
}
@@ -8014,11 +7612,49 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
}
pos = save_cursor = curwin->w_cursor;
+ pos_T firstpos = { 0 };
memset(&sia, 0, sizeof(sia));
sia.sa_stop_lnum = (linenr_T)lnum_stop;
sia.sa_tm = &tm;
- subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1,
- options, RE_SEARCH, &sia);
+
+ // Repeat until {skip} returns false.
+ for (;;) {
+ subpatnum
+ = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1, options, RE_SEARCH, &sia);
+ // finding the first match again means there is no match where {skip}
+ // evaluates to zero.
+ if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
+ subpatnum = FAIL;
+ }
+
+ if (subpatnum == FAIL || !use_skip) {
+ // didn't find it or no skip argument
+ break;
+ }
+ firstpos = pos;
+
+ // If the skip expression matches, ignore this match.
+ {
+ const pos_T save_pos = curwin->w_cursor;
+
+ curwin->w_cursor = pos;
+ bool err = false;
+ const bool do_skip = eval_expr_to_bool(&argvars[4], &err);
+ curwin->w_cursor = save_pos;
+ if (err) {
+ // Evaluating {skip} caused an error, break here.
+ subpatnum = FAIL;
+ break;
+ }
+ if (!do_skip) {
+ break;
+ }
+ }
+
+ // clear the start flag to avoid getting stuck here
+ options &= ~SEARCH_START;
+ }
+
if (subpatnum != FAIL) {
if (flags & SP_SUBPAT) {
retval = subpatnum;
@@ -8051,7 +7687,7 @@ theend:
return retval;
}
-// "rpcnotify()" function
+/// "rpcnotify()" function
static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8086,7 +7722,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 1;
}
-// "rpcrequest()" function
+/// "rpcrequest()" function
static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8114,7 +7750,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
sctx_T save_current_sctx;
- uint8_t *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
+ char *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
linenr_T save_sourcing_lnum;
int save_autocmd_bufnr;
funccal_entry_T funccal_entry;
@@ -8139,13 +7775,13 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_current_funccal((funccall_T *)(provider_caller_scope.funccalp));
}
-
Error err = ERROR_INIT;
uint64_t chan_id = (uint64_t)argvars[0].vval.v_number;
const char *method = tv_get_string(&argvars[1]);
- Object result = rpc_send_call(chan_id, method, args, &err);
+ ArenaMem res_mem = NULL;
+ Object result = rpc_send_call(chan_id, method, args, &res_mem, &err);
if (l_provider_call_nesting) {
current_sctx = save_current_sctx;
@@ -8180,11 +7816,11 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
end:
- api_free_object(result);
+ arena_mem_free(res_mem, NULL);
api_clear_error(&err);
}
-// "rpcstart()" function (DEPRECATED)
+/// "rpcstart()" function (DEPRECATED)
static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8228,7 +7864,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char **argv = xmalloc(sizeof(char_u *) * argvl);
// Copy program name
- argv[0] = xstrdup((char *)argvars[0].vval.v_string);
+ argv[0] = xstrdup(argvars[0].vval.v_string);
int i = 1;
// Copy arguments to the vector
@@ -8251,7 +7887,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "rpcstop()" function
+/// "rpcstop()" function
static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8281,54 +7917,57 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "screenattr()" function
+/// "screenattr()" function
static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int c;
+ ScreenGrid *grid;
int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
c = -1;
} else {
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
c = grid->attrs[grid->line_offset[row] + col];
}
rettv->vval.v_number = c;
}
-// "screenchar()" function
+/// "screenchar()" function
static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int c;
+ ScreenGrid *grid;
int row = tv_get_number_chk(&argvars[0], NULL) - 1;
int col = tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
c = -1;
} else {
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
- c = utf_ptr2char(grid->chars[grid->line_offset[row] + col]);
+ c = utf_ptr2char((char *)grid->chars[grid->line_offset[row] + col]);
}
rettv->vval.v_number = c;
}
-// "screenchars()" function
+/// "screenchars()" function
static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
+ ScreenGrid *grid;
int row = tv_get_number_chk(&argvars[0], NULL) - 1;
int col = tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
tv_list_alloc_ret(rettv, 0);
return;
}
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
int pcc[MAX_MCO];
int c = utfc_ptr2char(grid->chars[grid->line_offset[row] + col], pcc);
int composing_len = 0;
@@ -8342,9 +7981,9 @@ static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "screencol()" function
-//
-// First column is 1 to be consistent with virtcol().
+/// "screencol()" function
+///
+/// First column is 1 to be consistent with virtcol().
static void f_screencol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_col() + 1;
@@ -8376,29 +8015,32 @@ static void f_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(dict, S_LEN("endcol"), ecol);
}
-// "screenrow()" function
+/// "screenrow()" function
static void f_screenrow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_row() + 1;
}
-// "screenstring()" function
+/// "screenstring()" function
static void f_screenstring(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
+
+ ScreenGrid *grid;
int row = tv_get_number_chk(&argvars[0], NULL) - 1;
int col = tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
return;
}
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
- rettv->vval.v_string = vim_strsave(grid->chars[grid->line_offset[row] + col]);
+
+ rettv->vval.v_string = (char *)vim_strsave(grid->chars[grid->line_offset[row] + col]);
}
-// "search()" function
+/// "search()" function
static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int flags = 0;
@@ -8406,9 +8048,7 @@ static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = search_cmn(argvars, NULL, &flags);
}
-/*
- * "searchdecl()" function
- */
+/// "searchdecl()" function
static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int locally = 1;
@@ -8430,9 +8070,7 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * Used by searchpair() and searchpairpos()
- */
+/// Used by searchpair() and searchpairpos()
static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
{
bool save_p_ws = p_ws;
@@ -8478,13 +8116,9 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
|| argvars[4].v_type == VAR_UNKNOWN) {
skip = NULL;
} else {
+ // Type is checked later.
skip = &argvars[4];
- if (skip->v_type != VAR_FUNC
- && skip->v_type != VAR_PARTIAL
- && skip->v_type != VAR_STRING) {
- semsg(_(e_invarg2), tv_get_string(&argvars[4]));
- goto theend; // Type error.
- }
+
if (argvars[5].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[5], NULL);
if (lnum_stop < 0) {
@@ -8510,17 +8144,13 @@ theend:
return retval;
}
-/*
- * "searchpair()" function
- */
+/// "searchpair()" function
static void f_searchpair(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = searchpair_cmn(argvars, NULL);
}
-/*
- * "searchpairpos()" function
- */
+/// "searchpairpos()" function
static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T match_pos;
@@ -8556,7 +8186,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
long time_limit)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
- char_u *save_cpo;
+ char *save_cpo;
char_u *pat, *pat2 = NULL, *pat3 = NULL;
long retval = 0;
pos_T pos;
@@ -8572,7 +8202,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.
save_cpo = p_cpo;
- p_cpo = empty_option;
+ p_cpo = (char *)empty_option;
// Set the time limit, if there is one.
tm = profile_setlimit(time_limit);
@@ -8595,10 +8225,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
}
if (skip != NULL) {
- // Empty string means to not use the skip expression.
- if (skip->v_type == VAR_STRING || skip->v_type == VAR_FUNC) {
- use_skip = skip->vval.v_string != NULL && *skip->vval.v_string != NUL;
- }
+ use_skip = eval_expr_valid_arg(skip);
}
save_cursor = curwin->w_cursor;
@@ -8699,19 +8326,17 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
xfree(pat2);
xfree(pat3);
- if (p_cpo == empty_option) {
+ if ((char_u *)p_cpo == empty_option) {
p_cpo = save_cpo;
} else {
// Darn, evaluating the {skip} expression changed the value.
- free_string_option(save_cpo);
+ free_string_option((char_u *)save_cpo);
}
return retval;
}
-/*
- * "searchpos()" function
- */
+/// "searchpos()" function
static void f_searchpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T match_pos;
@@ -8765,7 +8390,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
address = xstrdup(tv_get_string(argvars));
}
} else {
- address = server_address_new();
+ address = server_address_new(NULL);
}
int result = server_start(address);
@@ -8781,7 +8406,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "localhost:" will now have a port), return the final value to the user.
size_t n;
char **addrs = server_address_list(&n);
- rettv->vval.v_string = (char_u *)addrs[n - 1];
+ rettv->vval.v_string = addrs[n - 1];
n--;
for (size_t i = 0; i < n; i++) {
@@ -8805,7 +8430,7 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (argvars[0].vval.v_string) {
- bool rv = server_stop((char *)argvars[0].vval.v_string);
+ bool rv = server_stop(argvars[0].vval.v_string);
rettv->vval.v_number = (rv ? 1 : 0);
}
}
@@ -8825,9 +8450,7 @@ static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setbufvar()" function
- */
+/// "setbufvar()" function
static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()
@@ -8871,6 +8494,49 @@ static void f_setbufvar(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.
+/// Otherwise use the column number as a byte offset.
+static void set_position(typval_T *argvars, typval_T *rettv, bool charpos)
+{
+ pos_T pos;
+ int fnum;
+ colnr_T curswant = -1;
+
+ rettv->vval.v_number = -1;
+ const char *const name = tv_get_string_chk(argvars);
+ if (name != NULL) {
+ if (list2fpos(&argvars[1], &pos, &fnum, &curswant, charpos) == OK) {
+ if (pos.col != MAXCOL && --pos.col < 0) {
+ pos.col = 0;
+ }
+ if (name[0] == '.' && name[1] == NUL) {
+ // set cursor; "fnum" is ignored
+ curwin->w_cursor = pos;
+ if (curswant >= 0) {
+ curwin->w_curswant = curswant - 1;
+ curwin->w_set_curswant = false;
+ }
+ check_cursor();
+ rettv->vval.v_number = 0;
+ } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
+ // set mark
+ if (setmark_pos((uint8_t)name[1], &pos, fnum, NULL) == OK) {
+ rettv->vval.v_number = 0;
+ }
+ } else {
+ emsg(_(e_invarg));
+ }
+ }
+ }
+}
+
+/// "setcharpos()" function
+static void f_setcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ set_position(argvars, rettv, true);
+}
+
static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *d;
@@ -8886,7 +8552,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (csearch != NULL) {
int pcc[MAX_MCO];
const int c = utfc_ptr2char(csearch, pcc);
- set_last_csearch(c, csearch, utfc_ptr2len(csearch));
+ set_last_csearch(c, csearch, utfc_ptr2len((char *)csearch));
}
di = tv_dict_find(d, S_LEN("forward"));
@@ -8901,9 +8567,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setcmdpos()" function
- */
+/// "setcmdpos()" function
static void f_setcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const int pos = (int)tv_get_number(&argvars[0]) - 1;
@@ -8913,6 +8577,12 @@ static void f_setcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+/// "setcursorcharpos" function
+static void f_setcursorcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ set_cursorpos(argvars, rettv, true);
+}
+
/// "setenv()" function
static void f_setenv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -8959,9 +8629,7 @@ static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = os_setperm(fname, mode) == OK;
}
-/*
- * "setline()" function
- */
+/// "setline()" function
static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = tv_get_lnum(&argvars[0]);
@@ -8988,7 +8656,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
{
static char *e_invact = N_("E927: Invalid action: '%s'");
const char *title = NULL;
- int action = ' ';
+ char action = ' ';
static int recursive = 0;
rettv->vval.v_number = -1;
dict_T *what = NULL;
@@ -9043,15 +8711,13 @@ skip_args:
recursive++;
list_T *const l = list_arg->vval.v_list;
- if (set_errorlist(wp, l, action, (char_u *)title, what) == OK) {
+ if (set_errorlist(wp, l, action, (char *)title, what) == OK) {
rettv->vval.v_number = 0;
}
recursive--;
}
-/*
- * "setloclist()" function
- */
+/// "setloclist()" function
static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *win;
@@ -9064,151 +8730,13 @@ static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setmatches()" function
- */
-static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- dict_T *d;
- list_T *s = NULL;
- win_T *win = get_optional_window(argvars, 1);
-
- rettv->vval.v_number = -1;
- if (argvars[0].v_type != VAR_LIST) {
- emsg(_(e_listreq));
- return;
- }
- if (win == NULL) {
- return;
- }
-
- list_T *const l = argvars[0].vval.v_list;
- // To some extent make sure that we are dealing with a list from
- // "getmatches()".
- int li_idx = 0;
- TV_LIST_ITER_CONST(l, li, {
- if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT
- || (d = TV_LIST_ITEM_TV(li)->vval.v_dict) == NULL) {
- semsg(_("E474: List item %d is either not a dictionary "
- "or an empty one"), li_idx);
- return;
- }
- if (!(tv_dict_find(d, S_LEN("group")) != NULL
- && (tv_dict_find(d, S_LEN("pattern")) != NULL
- || tv_dict_find(d, S_LEN("pos1")) != NULL)
- && tv_dict_find(d, S_LEN("priority")) != NULL
- && tv_dict_find(d, S_LEN("id")) != NULL)) {
- semsg(_("E474: List item %d is missing one of the required keys"),
- li_idx);
- return;
- }
- li_idx++;
- });
-
- clear_matches(win);
- bool match_add_failed = false;
- TV_LIST_ITER_CONST(l, li, {
- int i = 0;
-
- d = TV_LIST_ITEM_TV(li)->vval.v_dict;
- dictitem_T *const di = tv_dict_find(d, S_LEN("pattern"));
- if (di == NULL) {
- if (s == NULL) {
- s = tv_list_alloc(9);
- }
-
- // match from matchaddpos()
- for (i = 1; i < 9; i++) {
- char buf[30]; // use 30 to avoid compiler warning
- snprintf(buf, sizeof(buf), "pos%d", i);
- dictitem_T *const pos_di = tv_dict_find(d, buf, -1);
- if (pos_di != NULL) {
- if (pos_di->di_tv.v_type != VAR_LIST) {
- return;
- }
-
- tv_list_append_tv(s, &pos_di->di_tv);
- tv_list_ref(s);
- } else {
- break;
- }
- }
- }
-
- // Note: there are three number buffers involved:
- // - group_buf below.
- // - numbuf in tv_dict_get_string().
- // - mybuf in tv_get_string().
- //
- // If you change this code make sure that buffers will not get
- // accidentally reused.
- char group_buf[NUMBUFLEN];
- const char *const group = tv_dict_get_string_buf(d, "group", group_buf);
- const int priority = (int)tv_dict_get_number(d, "priority");
- const int id = (int)tv_dict_get_number(d, "id");
- dictitem_T *const conceal_di = tv_dict_find(d, S_LEN("conceal"));
- const char *const conceal = (conceal_di != NULL
- ? tv_get_string(&conceal_di->di_tv)
- : NULL);
- if (i == 0) {
- if (match_add(win, group,
- tv_dict_get_string(d, "pattern", false),
- priority, id, NULL, conceal) != id) {
- match_add_failed = true;
- }
- } else {
- if (match_add(win, group, NULL, priority, id, s, conceal) != id) {
- match_add_failed = true;
- }
- tv_list_unref(s);
- s = NULL;
- }
- });
- if (!match_add_failed) {
- rettv->vval.v_number = 0;
- }
-}
-
-/*
- * "setpos()" function
- */
+/// "setpos()" function
static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T pos;
- int fnum;
- colnr_T curswant = -1;
-
- rettv->vval.v_number = -1;
- const char *const name = tv_get_string_chk(argvars);
- if (name != NULL) {
- if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK) {
- if (pos.col != MAXCOL && --pos.col < 0) {
- pos.col = 0;
- }
- if (name[0] == '.' && name[1] == NUL) {
- // set cursor; "fnum" is ignored
- curwin->w_cursor = pos;
- if (curswant >= 0) {
- curwin->w_curswant = curswant - 1;
- curwin->w_set_curswant = false;
- }
- check_cursor();
- rettv->vval.v_number = 0;
- } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
- // set mark
- if (setmark_pos((uint8_t)name[1], &pos, fnum) == OK) {
- rettv->vval.v_number = 0;
- }
- } else {
- emsg(_(e_invarg));
- }
- }
- }
+ set_position(argvars, rettv, false);
}
-/*
- * "setqflist()" function
- */
+/// "setqflist()" function
static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
set_qf_ll_list(NULL, argvars, rettv);
@@ -9244,12 +8772,9 @@ static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *c
return OK;
}
-/*
- * "setreg()" function
- */
+/// "setreg()" function
static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int regname;
bool append = false;
MotionType yank_type;
long block_len;
@@ -9263,13 +8788,13 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (strregname == NULL) {
return; // Type error; errmsg already given.
}
- regname = (uint8_t)(*strregname);
+ char regname = (uint8_t)(*strregname);
if (regname == 0 || regname == '@') {
regname = '"';
}
const typval_T *regcontents = NULL;
- int pointreg = 0;
+ char pointreg = 0;
if (argvars[1].v_type == VAR_DICT) {
dict_T *const d = argvars[1].vval.v_dict;
@@ -9387,14 +8912,11 @@ free_lstval:
if (set_unnamed) {
// Discard the result. We already handle the error case.
- if (op_reg_set_previous(regname)) {
- }
+ op_reg_set_previous(regname);
}
}
-/*
- * "settabvar()" function
- */
+/// "settabvar()" function
static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
@@ -9425,21 +8947,19 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "settabwinvar()" function
- */
+/// "settabwinvar()" function
static void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
setwinvar(argvars, rettv, 1);
}
-// "settagstack()" function
+/// "settagstack()" function
static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
static char *e_invact2 = N_("E962: Invalid action: '%s'");
win_T *wp;
dict_T *d;
- int action = 'r';
+ char action = 'r';
rettv->vval.v_number = -1;
@@ -9486,9 +9006,7 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setwinvar()" function
- */
+/// "setwinvar()" function
static void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
setwinvar(argvars, rettv, 0);
@@ -9501,26 +9019,22 @@ static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *hash = sha256_bytes((const uint8_t *)p, strlen(p), NULL, 0);
// make a copy of the hash (sha256_bytes returns a static buffer)
- rettv->vval.v_string = (char_u *)xstrdup(hash);
+ rettv->vval.v_string = xstrdup(hash);
rettv->v_type = VAR_STRING;
}
-/*
- * "shellescape({string})" function
- */
+/// "shellescape({string})" function
static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const bool do_special = non_zero_arg(&argvars[1]);
- rettv->vval.v_string = vim_strsave_shellescape((const char_u *)tv_get_string(
- &argvars[0]), do_special,
- do_special);
+ rettv->vval.v_string =
+ (char *)vim_strsave_shellescape((const char_u *)tv_get_string(&argvars[0]), do_special,
+ do_special);
rettv->v_type = VAR_STRING;
}
-/*
- * shiftwidth() function
- */
+/// shiftwidth() function
static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
@@ -9538,280 +9052,12 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = get_sw_value(curbuf);
}
-/// "sign_define()" function
-static void f_sign_define(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *name;
-
- if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) {
- // Define multiple signs
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- sign_define_multiple(argvars[0].vval.v_list, rettv->vval.v_list);
- return;
- }
-
- // Define a single sign
- rettv->vval.v_number = -1;
-
- name = tv_get_string_chk(&argvars[0]);
- if (name == NULL) {
- return;
- }
-
- if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_DICT) {
- emsg(_(e_dictreq));
- return;
- }
-
- rettv->vval.v_number = sign_define_from_dict(name,
- argvars[1].v_type ==
- VAR_DICT ? argvars[1].vval.v_dict : NULL);
-}
-
-/// "sign_getdefined()" function
-static void f_sign_getdefined(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *name = NULL;
-
- tv_list_alloc_ret(rettv, 0);
-
- if (argvars[0].v_type != VAR_UNKNOWN) {
- name = tv_get_string(&argvars[0]);
- }
-
- sign_getlist((const char_u *)name, rettv->vval.v_list);
-}
-
-/// "sign_getplaced()" function
-static void f_sign_getplaced(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- buf_T *buf = NULL;
- dict_T *dict;
- dictitem_T *di;
- linenr_T lnum = 0;
- int sign_id = 0;
- const char *group = NULL;
- bool notanum = false;
-
- tv_list_alloc_ret(rettv, 0);
-
- if (argvars[0].v_type != VAR_UNKNOWN) {
- // get signs placed in the specified buffer
- buf = get_buf_arg(&argvars[0]);
- if (buf == NULL) {
- return;
- }
-
- if (argvars[1].v_type != VAR_UNKNOWN) {
- if (argvars[1].v_type != VAR_DICT
- || ((dict = argvars[1].vval.v_dict) == NULL)) {
- emsg(_(e_dictreq));
- return;
- }
- if ((di = tv_dict_find(dict, "lnum", -1)) != NULL) {
- // get signs placed at this line
- lnum = (linenr_T)tv_get_number_chk(&di->di_tv, &notanum);
- if (notanum) {
- return;
- }
- (void)lnum;
- lnum = tv_get_lnum(&di->di_tv);
- }
- if ((di = tv_dict_find(dict, "id", -1)) != NULL) {
- // get sign placed with this identifier
- sign_id = (int)tv_get_number_chk(&di->di_tv, &notanum);
- if (notanum) {
- return;
- }
- }
- if ((di = tv_dict_find(dict, "group", -1)) != NULL) {
- group = tv_get_string_chk(&di->di_tv);
- if (group == NULL) {
- return;
- }
- if (*group == '\0') { // empty string means global group
- group = NULL;
- }
- }
- }
- }
-
- sign_get_placed(buf, lnum, sign_id, (const char_u *)group,
- rettv->vval.v_list);
-}
-
-/// "sign_jump()" function
-static void f_sign_jump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- int sign_id;
- char *sign_group = NULL;
- buf_T *buf;
- bool notanum = false;
-
- rettv->vval.v_number = -1;
-
- // Sign identifier
- sign_id = (int)tv_get_number_chk(&argvars[0], &notanum);
- if (notanum) {
- return;
- }
- if (sign_id <= 0) {
- emsg(_(e_invarg));
- return;
- }
-
- // Sign group
- const char *sign_group_chk = tv_get_string_chk(&argvars[1]);
- if (sign_group_chk == NULL) {
- return;
- }
- if (sign_group_chk[0] == '\0') {
- sign_group = NULL; // global sign group
- } else {
- sign_group = xstrdup(sign_group_chk);
- }
-
- // Buffer to place the sign
- buf = get_buf_arg(&argvars[2]);
- if (buf == NULL) {
- goto cleanup;
- }
-
- rettv->vval.v_number = sign_jump(sign_id, (char_u *)sign_group, buf);
-
-cleanup:
- xfree(sign_group);
-}
-
-/// "sign_place()" function
-static void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- dict_T *dict = NULL;
-
- rettv->vval.v_number = -1;
-
- if (argvars[4].v_type != VAR_UNKNOWN
- && (argvars[4].v_type != VAR_DICT
- || ((dict = argvars[4].vval.v_dict) == NULL))) {
- emsg(_(e_dictreq));
- return;
- }
-
- rettv->vval.v_number = sign_place_from_dict(&argvars[0], &argvars[1], &argvars[2], &argvars[3],
- dict);
-}
-
-/// "sign_placelist()" function. Place multiple signs.
-static void f_sign_placelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- int sign_id;
-
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- if (argvars[0].v_type != VAR_LIST) {
- emsg(_(e_listreq));
- return;
- }
-
- // Process the List of sign attributes
- TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
- sign_id = -1;
- if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- sign_id = sign_place_from_dict(NULL, NULL, NULL, NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
- } else {
- emsg(_(e_dictreq));
- }
- tv_list_append_number(rettv->vval.v_list, sign_id);
- });
-}
-
-/// "sign_undefine()" function
-static void f_sign_undefine(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *name;
-
- if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) {
- // Undefine multiple signs
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- sign_undefine_multiple(argvars[0].vval.v_list, rettv->vval.v_list);
- return;
- }
-
- rettv->vval.v_number = -1;
-
- if (argvars[0].v_type == VAR_UNKNOWN) {
- // Free all the signs
- free_signs();
- rettv->vval.v_number = 0;
- } else {
- // Free only the specified sign
- name = tv_get_string_chk(&argvars[0]);
- if (name == NULL) {
- return;
- }
-
- if (sign_undefine_by_name((const char_u *)name) == OK) {
- rettv->vval.v_number = 0;
- }
- }
-}
-
-/// "sign_unplace()" function
-static void f_sign_unplace(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- dict_T *dict = NULL;
-
- rettv->vval.v_number = -1;
-
- if (argvars[0].v_type != VAR_STRING) {
- emsg(_(e_invarg));
- return;
- }
-
- if (argvars[1].v_type != VAR_UNKNOWN) {
- if (argvars[1].v_type != VAR_DICT) {
- emsg(_(e_dictreq));
- return;
- }
- dict = argvars[1].vval.v_dict;
- }
-
- rettv->vval.v_number = sign_unplace_from_dict(&argvars[0], dict);
-}
-
-/// "sign_unplacelist()" function
-static void f_sign_unplacelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- int retval;
-
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- if (argvars[0].v_type != VAR_LIST) {
- emsg(_(e_listreq));
- return;
- }
-
- TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
- retval = -1;
- if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- retval = sign_unplace_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
- } else {
- emsg(_(e_dictreq));
- }
- tv_list_append_number(rettv->vval.v_list, retval);
- });
-}
-
-/*
- * "simplify()" function
- */
+/// "simplify()" function
static void f_simplify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const p = tv_get_string(&argvars[0]);
- rettv->vval.v_string = (char_u *)xstrdup(p);
- simplify_filename(rettv->vval.v_string); // Simplify in place.
+ rettv->vval.v_string = xstrdup(p);
+ simplify_filename((char_u *)rettv->vval.v_string); // Simplify in place.
rettv->v_type = VAR_STRING;
}
@@ -9883,9 +9129,7 @@ static sortinfo_T *sortinfo = NULL;
#define ITEM_COMPARE_FAIL 999
-/*
- * Compare functions for f_sort() and f_uniq() below.
- */
+/// Compare functions for f_sort() and f_uniq() below.
static int item_compare(const void *s1, const void *s2, bool keep_zero)
{
ListSortItem *const si1 = (ListSortItem *)s1;
@@ -9924,7 +9168,7 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero)
if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
p1 = "'";
} else {
- p1 = (char *)tv1->vval.v_string;
+ p1 = tv1->vval.v_string;
}
} else {
tofree1 = p1 = encode_tv2string(tv1, NULL);
@@ -9933,7 +9177,7 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero)
if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
p2 = "'";
} else {
- p2 = (char *)tv2->vval.v_string;
+ p2 = tv2->vval.v_string;
}
} else {
tofree2 = p2 = encode_tv2string(tv2, NULL);
@@ -10014,7 +9258,7 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
funcexe.evaluate = true;
funcexe.partial = partial;
funcexe.selfdict = sortinfo->item_compare_selfdict;
- res = call_func((const char_u *)func_name, -1, &rettv, 2, argv, &funcexe);
+ res = call_func(func_name, -1, &rettv, 2, argv, &funcexe);
tv_clear(&argv[0]);
tv_clear(&argv[1]);
@@ -10022,6 +9266,11 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
res = ITEM_COMPARE_FAIL;
} else {
res = tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err);
+ if (res > 0) {
+ res = 1;
+ } else if (res < 0) {
+ res = -1;
+ }
}
if (sortinfo->item_compare_func_err) {
res = ITEM_COMPARE_FAIL; // return value has wrong type
@@ -10049,9 +9298,7 @@ static int item_compare2_not_keeping_zero(const void *s1, const void *s2)
return item_compare2(s1, s2, false);
}
-/*
- * "sort({list})" function
- */
+/// "sort({list})" function
static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
{
ListSortItem *ptrs;
@@ -10209,7 +9456,6 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-
bool rpc = false;
CallbackReader on_stdin = CALLBACK_READER_INIT;
dict_T *opts = argvars[0].vval.v_dict;
@@ -10218,6 +9464,10 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!tv_dict_get_callback(opts, S_LEN("on_stdin"), &on_stdin.cb)) {
return;
}
+ if (!tv_dict_get_callback(opts, S_LEN("on_print"), &on_print)) {
+ return;
+ }
+
on_stdin.buffered = tv_dict_get_number(opts, "stdin_buffered");
if (on_stdin.buffered && on_stdin.cb.type == kCallbackNone) {
on_stdin.self = opts;
@@ -10229,7 +9479,6 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
semsg(e_stdiochan2, error);
}
-
rettv->vval.v_number = (varnumber_T)id;
rettv->v_type = VAR_NUMBER;
}
@@ -10240,7 +9489,7 @@ static void f_uniq(typval_T *argvars, typval_T *rettv, FunPtr fptr)
do_sort_uniq(argvars, rettv, false);
}
-// "reltimefloat()" function
+/// "reltimefloat()" function
static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
@@ -10253,19 +9502,15 @@ static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "soundfold({word})" function
- */
+/// "soundfold({word})" function
static void f_soundfold(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
const char *const s = tv_get_string(&argvars[0]);
- rettv->vval.v_string = (char_u *)eval_soundfold(s);
+ rettv->vval.v_string = eval_soundfold(s);
}
-/*
- * "spellbadword()" function
- */
+/// "spellbadword()" function
static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *word = "";
@@ -10324,9 +9569,7 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
NULL), -1);
}
-/*
- * "spellsuggest()" function
- */
+/// "spellsuggest()" function
static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool typeerr = false;
@@ -10346,26 +9589,24 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- if (*curwin->w_s->b_p_spl != NUL) {
- const char *const str = tv_get_string(&argvars[0]);
- if (argvars[1].v_type != VAR_UNKNOWN) {
- maxcount = tv_get_number_chk(&argvars[1], &typeerr);
- if (maxcount <= 0) {
+ const char *const str = tv_get_string(&argvars[0]);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ maxcount = tv_get_number_chk(&argvars[1], &typeerr);
+ if (maxcount <= 0) {
+ goto f_spellsuggest_return;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ need_capital = tv_get_number_chk(&argvars[2], &typeerr);
+ if (typeerr) {
goto f_spellsuggest_return;
}
- if (argvars[2].v_type != VAR_UNKNOWN) {
- need_capital = tv_get_number_chk(&argvars[2], &typeerr);
- if (typeerr) {
- goto f_spellsuggest_return;
- }
- }
- } else {
- maxcount = 25;
}
-
- spell_suggest_list(&ga, (char_u *)str, maxcount, need_capital, false);
+ } else {
+ maxcount = 25;
}
+ spell_suggest_list(&ga, (char_u *)str, maxcount, need_capital, false);
+
f_spellsuggest_return:
tv_list_alloc_ret(rettv, (ptrdiff_t)ga.ga_len);
for (int i = 0; i < ga.ga_len; i++) {
@@ -10378,7 +9619,7 @@ f_spellsuggest_return:
static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *save_cpo;
+ char *save_cpo;
int match;
colnr_T col = 0;
bool keepempty = false;
@@ -10386,7 +9627,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
- p_cpo = (char_u *)"";
+ p_cpo = "";
const char *str = tv_get_string(&argvars[0]);
const char *pat = NULL;
@@ -10411,7 +9652,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
regmatch_T regmatch = {
- .regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING),
+ .regprog = vim_regcomp((char *)pat, RE_MAGIC + RE_STRING),
.startp = { NULL },
.endp = { NULL },
.rm_ic = false,
@@ -10443,7 +9684,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
col = 0;
} else {
// Don't get stuck at the same match.
- col = utfc_ptr2len(regmatch.endp[0]);
+ col = utfc_ptr2len((char *)regmatch.endp[0]);
}
str = (const char *)regmatch.endp[0];
}
@@ -10467,11 +9708,17 @@ static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (strequal(p, "config")) {
- rettv->vval.v_string = (char_u *)get_xdg_home(kXDGConfigHome);
+ rettv->vval.v_string = get_xdg_home(kXDGConfigHome);
} else if (strequal(p, "data")) {
- rettv->vval.v_string = (char_u *)get_xdg_home(kXDGDataHome);
+ rettv->vval.v_string = get_xdg_home(kXDGDataHome);
} else if (strequal(p, "cache")) {
- rettv->vval.v_string = (char_u *)get_xdg_home(kXDGCacheHome);
+ rettv->vval.v_string = get_xdg_home(kXDGCacheHome);
+ } else if (strequal(p, "state")) {
+ rettv->vval.v_string = get_xdg_home(kXDGStateHome);
+ } else if (strequal(p, "log")) {
+ rettv->vval.v_string = get_xdg_home(kXDGStateHome);
+ } else if (strequal(p, "run")) {
+ rettv->vval.v_string = stdpaths_get_xdg_var(kXDGRuntimeDir);
} else if (strequal(p, "config_dirs")) {
get_xdg_var_list(kXDGConfigDirs, rettv);
} else if (strequal(p, "data_dirs")) {
@@ -10481,36 +9728,34 @@ static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "str2float()" function
- */
+/// "str2float()" function
static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ char *p = skipwhite(tv_get_string(&argvars[0]));
bool isneg = (*p == '-');
if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
}
- (void)string2float((char *)p, &rettv->vval.v_float);
+ (void)string2float(p, &rettv->vval.v_float);
if (isneg) {
rettv->vval.v_float *= -1;
}
rettv->v_type = VAR_FLOAT;
}
-// "str2list()" function
+/// "str2list()" function
static void f_str2list(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, kListLenUnknown);
const char_u *p = (const char_u *)tv_get_string(&argvars[0]);
- for (; *p != NUL; p += utf_ptr2len(p)) {
- tv_list_append_number(rettv->vval.v_list, utf_ptr2char(p));
+ for (; *p != NUL; p += utf_ptr2len((char *)p)) {
+ tv_list_append_number(rettv->vval.v_list, utf_ptr2char((char *)p));
}
}
-// "str2nr()" function
+/// "str2nr()" function
static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int base = 10;
@@ -10528,10 +9773,10 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ char_u *p = (char_u *)skipwhite(tv_get_string(&argvars[0]));
bool isneg = (*p == '-');
if (*p == '+' || *p == '-') {
- p = skipwhite(p + 1);
+ p = (char_u *)skipwhite((char *)p + 1);
}
switch (base) {
case 2:
@@ -10553,9 +9798,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "strftime({format}[, {time}])" function
- */
+/// "strftime({format}[, {time}])" function
static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
time_t seconds;
@@ -10573,7 +9816,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime);
// MSVC returns NULL for an invalid value of seconds.
if (curtime_ptr == NULL) {
- rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
+ rettv->vval.v_string = xstrdup(_("(Invalid)"));
} else {
vimconv_T conv;
char_u *enc;
@@ -10596,9 +9839,9 @@ 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 = string_convert(&conv, (char_u *)result_buf, NULL);
+ rettv->vval.v_string = (char *)string_convert(&conv, (char_u *)result_buf, NULL);
} else {
- rettv->vval.v_string = (char_u *)xstrdup(result_buf);
+ rettv->vval.v_string = xstrdup(result_buf);
}
// Release conversion descriptors.
@@ -10607,7 +9850,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "strgetchar()" function
+/// "strgetchar()" function
static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -10627,17 +9870,15 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
while (charidx >= 0 && byteidx < len) {
if (charidx == 0) {
- rettv->vval.v_number = utf_ptr2char((const char_u *)str + byteidx);
+ rettv->vval.v_number = utf_ptr2char(str + byteidx);
break;
}
charidx--;
- byteidx += utf_ptr2len((const char_u *)str + byteidx);
+ byteidx += utf_ptr2len(str + byteidx);
}
}
-/*
- * "stridx()" function
- */
+/// "stridx()" function
static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -10669,26 +9910,20 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "string()" function
- */
-void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+/// "string()" function
+static void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)encode_tv2string(&argvars[0], NULL);
+ rettv->vval.v_string = encode_tv2string(&argvars[0], NULL);
}
-/*
- * "strlen()" function
- */
+/// "strlen()" function
static void f_strlen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0]));
}
-/*
- * "strchars()" function
- */
+/// "strchars()" function
static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *s = tv_get_string(&argvars[0]);
@@ -10711,9 +9946,7 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "strdisplaywidth()" function
- */
+/// "strdisplaywidth()" function
static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const s = tv_get_string(&argvars[0]);
@@ -10726,17 +9959,15 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char_u *)s) - col);
}
-/*
- * "strwidth()" function
- */
+/// "strwidth()" function
static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const s = tv_get_string(&argvars[0]);
- rettv->vval.v_number = (varnumber_T)mb_string2cells((const char_u *)s);
+ rettv->vval.v_number = (varnumber_T)mb_string2cells(s);
}
-// "strcharpart()" function
+/// "strcharpart()" function
static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const p = tv_get_string(&argvars[0]);
@@ -10748,7 +9979,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!error) {
if (nchar > 0) {
while (nchar > 0 && (size_t)nbyte < slen) {
- nbyte += utf_ptr2len((const char_u *)p + nbyte);
+ nbyte += utf_ptr2len(p + nbyte);
nchar--;
}
} else {
@@ -10764,7 +9995,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (off < 0) {
len += 1;
} else {
- len += utf_ptr2len((const char_u *)p + off);
+ len += utf_ptr2len(p + off);
}
charlen--;
}
@@ -10787,12 +10018,10 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)xstrndup(p + nbyte, (size_t)len);
+ rettv->vval.v_string = xstrndup(p + nbyte, (size_t)len);
}
-/*
- * "strpart()" function
- */
+/// "strpart()" function
static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool error = false;
@@ -10829,16 +10058,16 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// length in characters
for (off = n; off < (int)slen && len > 0; len--) {
- off += utfc_ptr2len((char_u *)p + off);
+ off += utfc_ptr2len(p + off);
}
len = off - n;
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len);
+ rettv->vval.v_string = xmemdupz(p + n, (size_t)len);
}
-// "strptime({format}, {timestring})" function
+/// "strptime({format}, {timestring})" function
static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char fmt_buf[NUMBUFLEN];
@@ -10870,9 +10099,7 @@ static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(enc);
}
-/*
- * "strridx()" function
- */
+/// "strridx()" function
static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
@@ -10915,18 +10142,14 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "strtrans()" function
- */
+/// "strtrans()" function
static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]), true);
+ rettv->vval.v_string = transstr(tv_get_string(&argvars[0]), true);
}
-/*
- * "submatch()" function
- */
+/// "submatch()" function
static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool error = false;
@@ -10950,16 +10173,14 @@ static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (retList == 0) {
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = reg_submatch(no);
+ rettv->vval.v_string = (char *)reg_submatch(no);
} else {
rettv->v_type = VAR_LIST;
rettv->vval.v_list = reg_submatch_list(no);
}
}
-/*
- * "substitute()" function
- */
+/// "substitute()" function
static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char patbuf[NUMBUFLEN];
@@ -10983,8 +10204,8 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|| flg == NULL) {
rettv->vval.v_string = NULL;
} else {
- rettv->vval.v_string = do_string_sub((char_u *)str, (char_u *)pat,
- (char_u *)sub, expr, (char_u *)flg);
+ rettv->vval.v_string = do_string_sub((char *)str, (char *)pat,
+ (char *)sub, expr, (char *)flg);
}
}
@@ -11005,7 +10226,7 @@ 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 = vim_strsave(buf->b_ml.ml_mfp->mf_fname);
+ rettv->vval.v_string = (char *)vim_strsave(buf->b_ml.ml_mfp->mf_fname);
}
}
@@ -11028,9 +10249,7 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = id;
}
-/*
- * "synIDattr(id, what [, mode])" function
- */
+/// "synIDattr(id, what [, mode])" function
static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const int id = (int)tv_get_number(&argvars[0]);
@@ -11049,7 +10268,6 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
modec = 'c';
}
-
const char *p = NULL;
switch (TOLOWER_ASC(what[0])) {
case 'b':
@@ -11086,21 +10304,35 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
break;
case 'u':
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- } else { // undercurl
- p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ if (STRLEN(what) >= 9) {
+ if (TOLOWER_ASC(what[5]) == 'l') {
+ // underline
+ p = highlight_has_attr(id, HL_UNDERLINE, modec);
+ } else if (TOLOWER_ASC(what[5]) != 'd') {
+ // undercurl
+ p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ } else if (TOLOWER_ASC(what[6]) != 'o') {
+ // underdashed
+ p = highlight_has_attr(id, HL_UNDERDASHED, modec);
+ } else if (TOLOWER_ASC(what[7]) == 'u') {
+ // underdouble
+ p = highlight_has_attr(id, HL_UNDERDOUBLE, modec);
+ } else {
+ // underdotted
+ p = highlight_has_attr(id, HL_UNDERDOTTED, modec);
+ }
+ } else {
+ // ul
+ p = highlight_color(id, what, modec);
}
break;
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p));
+ rettv->vval.v_string = (char *)(p == NULL ? p : xstrdup(p));
}
-/*
- * "synIDtrans(id)" function
- */
+/// "synIDtrans(id)" function
static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int id = tv_get_number(&argvars[0]);
@@ -11114,9 +10346,7 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = id;
}
-/*
- * "synconcealed(lnum, col)" function
- */
+/// "synconcealed(lnum, col)" function
static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int syntax_flags = 0;
@@ -11146,7 +10376,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
: curwin->w_p_lcs_chars.conceal;
}
if (cchar != NUL) {
- utf_char2bytes(cchar, str);
+ utf_char2bytes(cchar, (char *)str);
}
}
}
@@ -11158,9 +10388,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, matchid);
}
-/*
- * "synstack(lnum, col)" function
- */
+/// "synstack(lnum, col)" function
static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_set_ret(rettv, NULL);
@@ -11195,10 +10423,7 @@ static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_system_output_as_rettv(argvars, rettv, true);
}
-
-/*
- * "tabpagebuflist()" function
- */
+/// "tabpagebuflist()" function
static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp = NULL;
@@ -11220,9 +10445,7 @@ static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "tabpagenr()" function
- */
+/// "tabpagenr()" function
static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
@@ -11234,9 +10457,7 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (strcmp(arg, "$") == 0) {
nr = tabpage_index(NULL) - 1;
} else if (strcmp(arg, "#") == 0) {
- nr = valid_tabpage(lastused_tabpage)
- ? tabpage_index(lastused_tabpage)
- : nr;
+ nr = valid_tabpage(lastused_tabpage) ? tabpage_index(lastused_tabpage) : 0;
} else {
semsg(_(e_invexpr2), arg);
}
@@ -11247,10 +10468,7 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = nr;
}
-
-/*
- * Common code for tabpagewinnr() and winnr().
- */
+/// Common code for tabpagewinnr() and winnr().
static int get_winnr(tabpage_T *tp, typval_T *argvar)
{
win_T *twin;
@@ -11315,9 +10533,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
return nr;
}
-/*
- * "tabpagewinnr()" function
- */
+/// "tabpagewinnr()" function
static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
@@ -11330,9 +10546,7 @@ static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = nr;
}
-/*
- * "tagfiles()" function
- */
+/// "tagfiles()" function
static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char *fname;
@@ -11351,9 +10565,7 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(fname);
}
-/*
- * "taglist()" function
- */
+/// "taglist()" function
static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const tag_pattern = tv_get_string(&argvars[0]);
@@ -11371,16 +10583,14 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
(char_u *)tag_pattern, (char_u *)fname);
}
-/*
- * "tempname()" function
- */
+/// "tempname()" function
static void f_tempname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_tempname();
+ rettv->vval.v_string = (char *)vim_tempname();
}
-// "termopen(cmd[, cwd])" function
+/// "termopen(cmd[, cwd])" function
static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -11466,19 +10676,25 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "./…" => "/home/foo/…"
vim_FullName(cwd, (char *)NameBuff, sizeof(NameBuff), false);
// "/home/foo/…" => "~/…"
- size_t len = home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true);
+ size_t len = home_replace(NULL, (char *)NameBuff, (char *)IObuff, sizeof(IObuff), true);
// Trim slash.
- if (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/') {
+ if (len != 1 && (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/')) {
IObuff[len - 1] = '\0';
}
+ if (len == 1 && IObuff[0] == '/') {
+ // Avoid ambiguity in the URI when CWD is root directory.
+ IObuff[1] = '.';
+ IObuff[2] = '\0';
+ }
+
// Terminal URI: "term://$CWD//$PID:$CMD"
snprintf((char *)NameBuff, sizeof(NameBuff), "term://%s//%d:%s",
(char *)IObuff, pid, cmd);
// at this point the buffer has no terminal instance associated yet, so unset
// the 'swapfile' option to ensure no swap file will be created
curbuf->b_p_swf = false;
- (void)setfname(curbuf, NameBuff, NULL, true);
+ (void)setfname(curbuf, (char *)NameBuff, NULL, true);
// Save the job id and pid in b:terminal_job_{id,pid}
Error err = ERROR_INIT;
// deprecated: use 'channel' buffer option
@@ -11493,24 +10709,6 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
channel_create_event(chan, NULL);
}
-// "test_garbagecollect_now()" function
-static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- // This is dangerous, any Lists and Dicts used internally may be freed
- // while still in use.
- garbage_collect(true);
-}
-
-// "test_write_list_log()" function
-static void f_test_write_list_log(typval_T *const argvars, typval_T *const rettv, FunPtr fptr)
-{
- const char *const fname = tv_get_string_chk(&argvars[0]);
- if (fname == NULL) {
- return;
- }
- list_write_log(fname);
-}
-
/// "timer_info([timer])" function
static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -11583,8 +10781,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer_start(tv_get_number(&argvars[0]), repeat, &callback);
}
-
-// "timer_stop(timerid)" function
+/// "timer_stop(timerid)" function
static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type != VAR_NUMBER) {
@@ -11605,29 +10802,21 @@ static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr)
timer_stop_all();
}
-/*
- * "tolower(string)" function
- */
+/// "tolower(string)" function
static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
- false);
+ rettv->vval.v_string = strcase_save(tv_get_string(&argvars[0]), false);
}
-/*
- * "toupper(string)" function
- */
+/// "toupper(string)" function
static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
- true);
+ rettv->vval.v_string = strcase_save(tv_get_string(&argvars[0]), true);
}
-/*
- * "tr(string, fromstr, tostr)" function
- */
+/// "tr(string, fromstr, tostr)" function
static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
@@ -11650,16 +10839,16 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool first = true;
while (*in_str != NUL) {
const char *cpstr = in_str;
- const int inlen = utfc_ptr2len((const char_u *)in_str);
+ const int inlen = utfc_ptr2len(in_str);
int cplen = inlen;
int idx = 0;
int fromlen;
for (const char *p = fromstr; *p != NUL; p += fromlen) {
- fromlen = utfc_ptr2len((const char_u *)p);
+ fromlen = utfc_ptr2len(p);
if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) {
int tolen;
for (p = tostr; *p != NUL; p += tolen) {
- tolen = utfc_ptr2len((const char_u *)p);
+ tolen = utfc_ptr2len(p);
if (idx-- == 0) {
cplen = tolen;
cpstr = (char *)p;
@@ -11681,7 +10870,7 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
first = false;
int tolen;
for (const char *p = tostr; *p != NUL; p += tolen) {
- tolen = utfc_ptr2len((const char_u *)p);
+ tolen = utfc_ptr2len(p);
idx--;
}
if (idx != 0) {
@@ -11704,10 +10893,9 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
error:
semsg(_(e_invarg2), fromstr);
ga_clear(&ga);
- return;
}
-// "trim({expr})" function
+/// "trim({expr})" function
static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf1[NUMBUFLEN];
@@ -11745,14 +10933,14 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (dir == 0 || dir == 1) {
// Trim leading characters
while (*head != NUL) {
- c1 = utf_ptr2char(head);
+ c1 = utf_ptr2char((char *)head);
if (mask == NULL) {
if (c1 > ' ' && c1 != 0xa0) {
break;
}
} else {
for (p = mask; *p != NUL; MB_PTR_ADV(p)) {
- if (c1 == utf_ptr2char(p)) {
+ if (c1 == utf_ptr2char((char *)p)) {
break;
}
}
@@ -11770,14 +10958,14 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
for (; tail > head; tail = prev) {
prev = tail;
MB_PTR_BACK(head, prev);
- c1 = utf_ptr2char(prev);
+ c1 = utf_ptr2char((char *)prev);
if (mask == NULL) {
if (c1 > ' ' && c1 != 0xa0) {
break;
}
} else {
for (p = mask; *p != NUL; MB_PTR_ADV(p)) {
- if (c1 == utf_ptr2char(p)) {
+ if (c1 == utf_ptr2char((char *)p)) {
break;
}
}
@@ -11787,12 +10975,10 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
- rettv->vval.v_string = vim_strnsave(head, tail - head);
+ rettv->vval.v_string = (char *)vim_strnsave(head, tail - head);
}
-/*
- * "type(expr)" function
- */
+/// "type(expr)" function
static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = -1;
@@ -11824,9 +11010,7 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "undofile(name)" function
- */
+/// "undofile(name)" function
static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -11839,15 +11023,13 @@ static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char *ffname = FullName_save(fname, true);
if (ffname != NULL) {
- rettv->vval.v_string = (char_u *)u_get_undo_file_name(ffname, false);
+ rettv->vval.v_string = u_get_undo_file_name(ffname, false);
}
xfree(ffname);
}
}
-/*
- * "undotree()" function
- */
+/// "undotree()" function
static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
@@ -11865,24 +11047,20 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_list(dict, S_LEN("entries"), u_eval_tree(curbuf->b_u_oldhead));
}
-/*
- * "values(dict)" function
- */
+/// "values(dict)" function
static void f_values(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 1);
}
-/*
- * "virtcol(string)" function
- */
+/// "virtcol(string)" function
static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T vcol = 0;
pos_T *fp;
int fnum = curbuf->b_fnum;
- fp = var2fpos(&argvars[0], FALSE, &fnum);
+ fp = var2fpos(&argvars[0], false, &fnum, false);
if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
&& fnum == curbuf->b_fnum) {
// Limit the column to a valid value, getvvcol() doesn't check.
@@ -11901,9 +11079,7 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = vcol;
}
-/*
- * "visualmode()" function
- */
+/// "visualmode()" function
static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u str[2];
@@ -11911,7 +11087,7 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
str[0] = curbuf->b_visual_mode_eval;
str[1] = NUL;
- rettv->vval.v_string = vim_strsave(str);
+ rettv->vval.v_string = (char *)vim_strsave(str);
// A non-zero number or non-empty string argument: reset mode.
if (non_zero_arg(&argvars[0])) {
@@ -11919,12 +11095,10 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "wildmenumode()" function
- */
+/// "wildmenumode()" function
static void f_wildmenumode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (wild_menu_showing || ((State & CMDLINE) && pum_visible())) {
+ if (wild_menu_showing || ((State & MODE_CMDLINE) && pum_visible())) {
rettv->vval.v_number = 1;
}
}
@@ -11952,21 +11126,20 @@ 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 = vim_strsave((char_u *)"unknown");
+ rettv->vval.v_string = (char *)vim_strsave((char_u *)"unknown");
return;
}
}
if (wp == aucmd_win) {
- rettv->vval.v_string = vim_strsave((char_u *)"autocmd");
+ rettv->vval.v_string = xstrdup("autocmd");
} else if (wp->w_p_pvw) {
- rettv->vval.v_string = vim_strsave((char_u *)"preview");
+ rettv->vval.v_string = xstrdup("preview");
} else if (wp->w_floating) {
- rettv->vval.v_string = vim_strsave((char_u *)"popup");
+ rettv->vval.v_string = xstrdup("popup");
} else if (wp == curwin && cmdwin_type != 0) {
- rettv->vval.v_string = vim_strsave((char_u *)"command");
+ rettv->vval.v_string = xstrdup("command");
} else if (bt_quickfix(wp->w_buffer)) {
- rettv->vval.v_string = vim_strsave((char_u *)(wp->w_llist_ref != NULL ?
- "loclist" : "quickfix"));
+ rettv->vval.v_string = xstrdup((wp->w_llist_ref != NULL ? "loclist" : "quickfix"));
}
}
@@ -11988,6 +11161,42 @@ static void f_win_id2win(typval_T *argvars, typval_T *rettv, FunPtr 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)
+{
+ win_T *wp;
+ int offset;
+
+ rettv->vval.v_number = false;
+
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL || wp->w_floating) {
+ return;
+ }
+
+ offset = (int)tv_get_number(&argvars[1]);
+ win_drag_vsep_line(wp, offset);
+ rettv->vval.v_number = true;
+}
+
+/// "win_move_statusline()" function
+static void f_win_move_statusline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ win_T *wp;
+ int offset;
+
+ rettv->vval.v_number = false;
+
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL || wp->w_floating) {
+ return;
+ }
+
+ offset = (int)tv_get_number(&argvars[1]);
+ win_drag_status_line(wp, offset);
+ rettv->vval.v_number = true;
+}
+
/// "winbufnr(nr)" function
static void f_winbufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -11999,9 +11208,7 @@ static void f_winbufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "wincol()" function
- */
+/// "wincol()" function
static void f_wincol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
validate_cursor();
@@ -12019,7 +11226,7 @@ static void f_winheight(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "winlayout()" function
+/// "winlayout()" function
static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tabpage_T *tp;
@@ -12038,18 +11245,14 @@ static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_framelayout(tp->tp_topframe, rettv->vval.v_list, true);
}
-/*
- * "winline()" function
- */
+/// "winline()" function
static void f_winline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
validate_cursor();
rettv->vval.v_number = curwin->w_wrow + 1;
}
-/*
- * "winnr()" function
- */
+/// "winnr()" function
static void f_winnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
@@ -12058,9 +11261,7 @@ static void f_winnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = nr;
}
-/*
- * "winrestcmd()" function
- */
+/// "winrestcmd()" function
static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
garray_T ga;
@@ -12087,9 +11288,7 @@ static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
}
-/*
- * "winrestview()" function
- */
+/// "winrestview()" function
static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *dict;
@@ -12140,9 +11339,7 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "winsaveview()" function
- */
+/// "winsaveview()" function
static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *dict;
@@ -12173,11 +11370,11 @@ static void f_winwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "windowsversion()" function
+/// "windowsversion()" function
static void f_windowsversion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)xstrdup(windowsVersion);
+ rettv->vval.v_string = xstrdup(windowsVersion);
}
/// "wordcount()" function
@@ -12264,9 +11461,8 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
-/*
- * "xor(expr, expr)" function
- */
+
+/// "xor(expr, expr)" function
static void f_xor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
diff --git a/src/nvim/eval/funcs.h b/src/nvim/eval/funcs.h
index c6a0cb959e..5f8d81c989 100644
--- a/src/nvim/eval/funcs.h
+++ b/src/nvim/eval/funcs.h
@@ -9,19 +9,20 @@ typedef void (*FunPtr)(void);
/// Prototype of C function that implements VimL function
typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, FunPtr data);
-/// Special flags for base_arg @see VimLFuncDef
+/// Special flags for base_arg @see EvalFuncDef
#define BASE_NONE 0 ///< Not a method (no base argument).
#define BASE_LAST UINT8_MAX ///< Use the last argument as the method base.
/// Structure holding VimL function definition
-typedef struct fst {
+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.
-} VimLFuncDef;
+} EvalFuncDef;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/funcs.h.generated.h"
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 42ac1839e6..e19cf411c0 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
+#include "lauxlib.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
#include "nvim/charset.h"
@@ -28,11 +29,11 @@
#include "nvim/mbyte.h"
#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/os/fileio.h"
#include "nvim/os/input.h"
#include "nvim/pos.h"
#include "nvim/types.h"
#include "nvim/vim.h"
-#include "nvim/os/fileio.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/typval.c.generated.h"
@@ -564,7 +565,7 @@ void tv_list_append_allocated_string(list_T *const l, char *const str)
tv_list_append_owned_tv(l, (typval_T) {
.v_type = VAR_STRING,
.v_lock = VAR_UNLOCKED,
- .vval.v_string = (char_u *)str,
+ .vval.v_string = str,
});
}
@@ -878,9 +879,9 @@ void tv_list_reverse(list_T *const l)
list_log(l, NULL, NULL, "reverse");
#define SWAP(a, b) \
do { \
- tmp = a; \
- a = b; \
- b = tmp; \
+ tmp = (a); \
+ (a) = (b); \
+ (b) = tmp; \
} while (0)
listitem_T *tmp;
@@ -1123,6 +1124,8 @@ bool tv_callback_equal(const Callback *cb1, const Callback *cb2)
// FIXME: this is inconsistent with tv_equal but is needed for precision
// maybe change dictwatcheradd to return a watcher id instead?
return cb1->data.partial == cb2->data.partial;
+ case kCallbackLua:
+ return cb1->data.luaref == cb2->data.luaref;
case kCallbackNone:
return true;
}
@@ -1136,12 +1139,15 @@ void callback_free(Callback *callback)
{
switch (callback->type) {
case kCallbackFuncref:
- func_unref(callback->data.funcref);
+ func_unref((char_u *)callback->data.funcref);
xfree(callback->data.funcref);
break;
case kCallbackPartial:
partial_unref(callback->data.partial);
break;
+ case kCallbackLua:
+ NLUA_CLEAR_REF(callback->data.luaref);
+ break;
case kCallbackNone:
break;
}
@@ -1161,9 +1167,14 @@ void callback_put(Callback *cb, typval_T *tv)
break;
case kCallbackFuncref:
tv->v_type = VAR_FUNC;
- tv->vval.v_string = vim_strsave(cb->data.funcref);
- func_ref(cb->data.funcref);
+ tv->vval.v_string = xstrdup(cb->data.funcref);
+ func_ref((char_u *)cb->data.funcref);
break;
+ case kCallbackLua:
+ // TODO(tjdevries): Unified Callback.
+ // At this point this isn't possible, but it'd be nice to put
+ // these handled more neatly in one place.
+ // So instead, we just do the default and put nil
default:
tv->v_type = VAR_SPECIAL;
tv->vval.v_special = kSpecialVarNull;
@@ -1182,8 +1193,11 @@ void callback_copy(Callback *dest, Callback *src)
dest->data.partial->pt_refcount++;
break;
case kCallbackFuncref:
- dest->data.funcref = vim_strsave(src->data.funcref);
- func_ref(src->data.funcref);
+ dest->data.funcref = xstrdup(src->data.funcref);
+ func_ref((char_u *)src->data.funcref);
+ break;
+ case kCallbackLua:
+ dest->data.luaref = api_new_luaref(src->data.luaref);
break;
default:
dest->data.funcref = NULL;
@@ -1191,6 +1205,30 @@ void callback_copy(Callback *dest, Callback *src)
}
}
+/// Generate a string description of a callback
+char *callback_to_string(Callback *cb)
+{
+ size_t msglen = 100;
+ char *msg = (char *)xmallocz(msglen);
+
+ switch (cb->type) {
+ case kCallbackLua:
+ snprintf(msg, msglen, "<lua: %d>", cb->data.luaref);
+ break;
+ case kCallbackFuncref:
+ // TODO(tjdevries): Is this enough space for this?
+ snprintf(msg, msglen, "<vim function: %s>", cb->data.funcref);
+ break;
+ case kCallbackPartial:
+ snprintf(msg, msglen, "<vim partial: %s>", cb->data.partial->pt_name);
+ break;
+ default:
+ snprintf(msg, msglen, "%s", "");
+ break;
+ }
+ return msg;
+}
+
/// Remove watcher from a dictionary
///
/// @param dict Dictionary to remove watcher from.
@@ -1274,7 +1312,7 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key, typval_T
argv[0].vval.v_dict = dict;
argv[1].v_type = VAR_STRING;
argv[1].v_lock = VAR_UNLOCKED;
- argv[1].vval.v_string = (char_u *)xstrdup(key);
+ argv[1].vval.v_string = xstrdup(key);
argv[2].v_type = VAR_DICT;
argv[2].v_lock = VAR_UNLOCKED;
argv[2].vval.v_dict = tv_dict_alloc();
@@ -1396,7 +1434,7 @@ dictitem_T *tv_dict_item_copy(dictitem_T *const di)
void tv_dict_item_remove(dict_T *const dict, dictitem_T *const item)
FUNC_ATTR_NONNULL_ALL
{
- hashitem_T *const hi = hash_find(&dict->dv_hashtab, item->di_key);
+ hashitem_T *const hi = hash_find(&dict->dv_hashtab, (char *)item->di_key);
if (HASHITEM_EMPTY(hi)) {
semsg(_(e_intern2), "tv_dict_item_remove()");
} else {
@@ -1501,7 +1539,6 @@ void tv_dict_free(dict_T *const d)
}
}
-
/// Unreference a dictionary
///
/// Decrements the reference count and frees dictionary when it becomes zero.
@@ -1530,7 +1567,7 @@ dictitem_T *tv_dict_find(const dict_T *const d, const char *const key, const ptr
return NULL;
}
hashitem_T *const hi = (len < 0
- ? hash_find(&d->dv_hashtab, (const char_u *)key)
+ ? hash_find(&d->dv_hashtab, key)
: hash_find_len(&d->dv_hashtab, key, (size_t)len));
if (HASHITEM_EMPTY(hi)) {
return NULL;
@@ -1574,8 +1611,6 @@ varnumber_T tv_dict_get_number(const dict_T *const d, const char *const key)
}
/// Converts a dict to an environment
-///
-///
char **tv_dict_to_env(dict_T *denv)
{
size_t env_size = (size_t)tv_dict_len(denv);
@@ -1894,7 +1929,7 @@ int tv_dict_add_allocated_str(dict_T *const d, const char *const key, const size
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
item->di_tv.v_type = VAR_STRING;
- item->di_tv.vval.v_string = (char_u *)val;
+ item->di_tv.vval.v_string = val;
if (tv_dict_add(d, item) == FAIL) {
tv_dict_item_free(item);
return FAIL;
@@ -2251,36 +2286,36 @@ void tv_blob_copy(typval_T *const from, typval_T *const to)
#define TYPVAL_ENCODE_CONV_NIL(tv) \
do { \
- tv->vval.v_special = kSpecialVarNull; \
- tv->v_lock = VAR_UNLOCKED; \
+ (tv)->vval.v_special = kSpecialVarNull; \
+ (tv)->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
do { \
- tv->vval.v_bool = kBoolVarFalse; \
- tv->v_lock = VAR_UNLOCKED; \
+ (tv)->vval.v_bool = kBoolVarFalse; \
+ (tv)->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
do { \
- (void)num; \
- tv->vval.v_number = 0; \
- tv->v_lock = VAR_UNLOCKED; \
+ (void)(num); \
+ (tv)->vval.v_number = 0; \
+ (tv)->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
do { \
- tv->vval.v_float = 0; \
- tv->v_lock = VAR_UNLOCKED; \
+ (tv)->vval.v_float = 0; \
+ (tv)->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
xfree(buf); \
- tv->vval.v_string = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
+ (tv)->vval.v_string = NULL; \
+ (tv)->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len)
@@ -2289,9 +2324,9 @@ void tv_blob_copy(typval_T *const from, typval_T *const to)
#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
do { \
- tv_blob_unref(tv->vval.v_blob); \
- tv->vval.v_blob = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
+ tv_blob_unref((tv)->vval.v_blob); \
+ (tv)->vval.v_blob = NULL; \
+ (tv)->v_lock = VAR_UNLOCKED; \
} while (0)
static inline int _nothing_conv_func_start(typval_T *const tv, char_u *const fun)
@@ -2348,9 +2383,9 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
do { \
- tv_list_unref(tv->vval.v_list); \
- tv->vval.v_list = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
+ tv_list_unref((tv)->vval.v_list); \
+ (tv)->vval.v_list = NULL; \
+ (tv)->v_lock = VAR_UNLOCKED; \
} while (0)
static inline void _nothing_conv_empty_dict(typval_T *const tv, dict_T **const dictp)
@@ -2364,8 +2399,8 @@ static inline void _nothing_conv_empty_dict(typval_T *const tv, dict_T **const d
}
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
do { \
- assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
- _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
+ assert((void *)&(dict) != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
+ _nothing_conv_empty_dict(tv, ((dict_T **)&(dict))); \
} while (0)
static inline int _nothing_conv_real_list_after_start(typval_T *const tv,
@@ -2386,7 +2421,7 @@ static inline int _nothing_conv_real_list_after_start(typval_T *const tv,
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \
do { \
- if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
+ if (_nothing_conv_real_list_after_start(tv, &(mpsv)) != NOTDONE) { \
goto typval_encode_stop_converting_one_item; \
} \
} while (0)
@@ -2426,8 +2461,9 @@ static inline int _nothing_conv_real_dict_after_start(typval_T *const tv, dict_T
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
do { \
- if (_nothing_conv_real_dict_after_start(tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
- &mpsv) != NOTDONE) { \
+ if (_nothing_conv_real_dict_after_start(tv, (dict_T **)&(dict), \
+ (void *)&TYPVAL_ENCODE_NODICT_VAR, &(mpsv)) \
+ != NOTDONE) { \
goto typval_encode_stop_converting_one_item; \
} \
} while (0)
@@ -2446,7 +2482,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, dict_T **const dic
}
}
#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- _nothing_conv_dict_end(tv, (dict_T **)&dict, \
+ _nothing_conv_dict_end(tv, (dict_T **)&(dict), \
(void *)&TYPVAL_ENCODE_NODICT_VAR)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
@@ -2520,7 +2556,7 @@ void tv_free(typval_T *tv)
partial_unref(tv->vval.v_partial);
break;
case VAR_FUNC:
- func_unref(tv->vval.v_string);
+ func_unref((char_u *)tv->vval.v_string);
FALLTHROUGH;
case VAR_STRING:
xfree(tv->vval.v_string);
@@ -2571,9 +2607,9 @@ void tv_copy(const typval_T *const from, typval_T *const to)
case VAR_STRING:
case VAR_FUNC:
if (from->vval.v_string != NULL) {
- to->vval.v_string = vim_strsave(from->vval.v_string);
+ to->vval.v_string = xstrdup(from->vval.v_string);
if (from->v_type == VAR_FUNC) {
- func_ref(to->vval.v_string);
+ func_ref((char_u *)to->vval.v_string);
}
}
break;
@@ -2628,9 +2664,9 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock, const boo
// lock/unlock the item itself
#define CHANGE_LOCK(lock, var) \
do { \
- var = ((VarLockStatus[]) { \
- [VAR_UNLOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \
- [VAR_LOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \
+ (var) = ((VarLockStatus[]) { \
+ [VAR_UNLOCKED] = ((lock) ? VAR_LOCKED : VAR_UNLOCKED), \
+ [VAR_LOCKED] = ((lock) ? VAR_LOCKED : VAR_UNLOCKED), \
[VAR_FIXED] = VAR_FIXED, \
})[var]; \
} while (0)
@@ -3059,7 +3095,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(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0,
+ vim_str2nr((char_u *)tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0,
false);
}
return n;
@@ -3091,7 +3127,7 @@ linenr_T tv_get_lnum(const typval_T *const tv)
linenr_T lnum = (linenr_T)tv_get_number_chk(tv, NULL);
if (lnum == 0) { // No valid number, try using same function as line() does.
int fnum;
- pos_T *const fp = var2fpos(tv, true, &fnum);
+ pos_T *const fp = var2fpos(tv, true, &fnum, false);
if (fp != NULL) {
lnum = fp->lnum;
}
@@ -3205,8 +3241,9 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
case VAR_BLOB:
case VAR_UNKNOWN:
emsg(_(str_errors[tv->v_type]));
- return false;
+ return NULL;
}
+ abort();
return NULL;
}
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index d1275d6512..c02351947b 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -72,16 +72,20 @@ typedef enum {
kCallbackNone = 0,
kCallbackFuncref,
kCallbackPartial,
+ kCallbackLua,
} CallbackType;
typedef struct {
union {
- char_u *funcref;
+ char *funcref;
partial_T *partial;
+ LuaRef luaref;
} data;
CallbackType type;
} Callback;
-#define CALLBACK_NONE ((Callback){ .type = kCallbackNone })
+
+#define CALLBACK_INIT { .type = kCallbackNone }
+#define CALLBACK_NONE ((Callback)CALLBACK_INIT)
/// Structure holding dictionary watcher
typedef struct dict_watcher {
@@ -129,19 +133,19 @@ typedef enum {
/// Structure that holds an internal variable value
typedef struct {
- VarType v_type; ///< Variable type.
- VarLockStatus v_lock; ///< Variable lock status.
+ VarType v_type; ///< Variable type.
+ VarLockStatus v_lock; ///< Variable lock status.
union typval_vval_union {
- varnumber_T v_number; ///< Number, for VAR_NUMBER.
+ 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_u *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.
+ 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
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index ece51cb046..73b36b8611 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -1,3 +1,5 @@
+// uncrustify:off
+
/// @file eval/typval_encode.c.h
///
/// Contains set of macros used to convert (possibly recursive) typval_T into
@@ -250,6 +252,8 @@
#include "nvim/func_attr.h"
#include "nvim/lib/kvec.h"
+// -V::1063
+
/// Dummy variable used because some macros need lvalue
///
/// Must not be written to, if needed one must check that address of the
@@ -335,7 +339,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
tv_blob_len(tv->vval.v_blob));
break;
case VAR_FUNC:
- TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string);
+ TYPVAL_ENCODE_CONV_FUNC_START(tv, (char_u *)tv->vval.v_string);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0);
TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
TYPVAL_ENCODE_CONV_FUNC_END(tv);
@@ -343,8 +347,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
case VAR_PARTIAL: {
partial_T *const pt = tv->vval.v_partial;
(void)pt;
- TYPVAL_ENCODE_CONV_FUNC_START( // -V547
- tv, (pt == NULL ? NULL : partial_name(pt)));
+ TYPVAL_ENCODE_CONV_FUNC_START(tv, (pt == NULL ? NULL : (char_u *)partial_name(pt))); // -V547
_mp_push(*mpstack, ((MPConvStackVal) { // -V779
.type = kMPConvPartial,
.tv = tv,
diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h
index d5cf431870..ed70ba87ec 100644
--- a/src/nvim/eval/typval_encode.h
+++ b/src/nvim/eval/typval_encode.h
@@ -85,9 +85,7 @@ static inline size_t tv_strlen(const typval_T *const tv)
static inline size_t tv_strlen(const typval_T *const tv)
{
assert(tv->v_type == VAR_STRING);
- return (tv->vval.v_string == NULL
- ? 0
- : strlen((char *)tv->vval.v_string));
+ return (tv->vval.v_string == NULL ? 0 : strlen(tv->vval.v_string));
}
/// Code for checking whether container references itself
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index eb241eb8ae..c2579944e4 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -70,7 +70,7 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, i
bool mustend = false;
char_u *arg = *argp;
char_u *p = arg;
- int c;
+ char_u c;
int i;
if (newargs != NULL) {
@@ -125,14 +125,14 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, i
*p = c;
}
- if (*skipwhite(p) == '=' && default_args != NULL) {
+ if (*skipwhite((char *)p) == '=' && default_args != NULL) {
typval_T rettv;
any_default = true;
- p = skipwhite(p) + 1;
- p = skipwhite(p);
+ p = (char_u *)skipwhite((char *)p) + 1;
+ p = (char_u *)skipwhite((char *)p);
char_u *expr = p;
- if (eval1(&p, &rettv, false) != FAIL) {
+ if (eval1((char **)&p, &rettv, false) != FAIL) {
ga_grow(default_args, 1);
// trim trailing whitespace
@@ -159,7 +159,7 @@ static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, i
mustend = true;
}
}
- p = skipwhite(p);
+ p = (char_u *)skipwhite((char *)p);
if (mustend && *p != endchar) {
if (!skip) {
semsg(_(e_invarg2), *argp);
@@ -200,8 +200,7 @@ static void register_closure(ufunc_T *fp)
[current_funccal->fc_funcs.ga_len++] = fp;
}
-
-/// Get a name for a lambda. Returned in static memory.
+/// @return a name for a lambda. Returned in static memory.
char_u *get_lambda_name(void)
{
static char_u name[30];
@@ -222,7 +221,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
partial_T *pt = NULL;
int varargs;
int ret;
- char_u *start = skipwhite(*arg + 1);
+ char_u *start = (char_u *)skipwhite((char *)(*arg) + 1);
char_u *s, *e;
bool *old_eval_lavars = eval_lavars_used;
bool eval_lavars = false;
@@ -239,7 +238,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
} else {
pnewargs = NULL;
}
- *arg = skipwhite(*arg + 1);
+ *arg = (char_u *)skipwhite((char *)(*arg) + 1);
ret = get_function_args(arg, '-', pnewargs, &varargs, NULL, false);
if (ret == FAIL || **arg != '>') {
goto errret;
@@ -251,21 +250,21 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
}
// Get the start and the end of the expression.
- *arg = skipwhite(*arg + 1);
+ *arg = (char_u *)skipwhite((char *)(*arg) + 1);
s = *arg;
- ret = skip_expr(arg);
+ ret = skip_expr((char **)arg);
if (ret == FAIL) {
goto errret;
}
e = *arg;
- *arg = skipwhite(*arg);
+ *arg = (char_u *)skipwhite((char *)(*arg));
if (**arg != '}') {
goto errret;
}
(*arg)++;
if (evaluate) {
- int len, flags = 0;
+ int flags = 0;
char_u *p;
garray_T newlines;
@@ -278,7 +277,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
ga_grow(&newlines, 1);
// Add "return " before the expression.
- len = 7 + e - s + 1;
+ size_t len = (size_t)(7 + e - s + 1);
p = (char_u *)xmalloc(len);
((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
STRCPY(p, "return ");
@@ -359,7 +358,7 @@ char_u *deref_func_name(const char *name, int *lenp, partial_T **const partialp,
return (char_u *)"";
}
*lenp = (int)STRLEN(v->di_tv.vval.v_string);
- return v->di_tv.vval.v_string;
+ return (char_u *)v->di_tv.vval.v_string;
}
if (v != NULL && v->di_tv.v_type == VAR_PARTIAL) {
@@ -372,7 +371,7 @@ char_u *deref_func_name(const char *name, int *lenp, partial_T **const partialp,
if (partialp != NULL) {
*partialp = pt;
}
- char_u *s = partial_name(pt);
+ char_u *s = (char_u *)partial_name(pt);
*lenp = (int)STRLEN(s);
return s;
}
@@ -422,11 +421,11 @@ int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, func
argp = *arg;
while (argcount < MAX_FUNC_ARGS
- (funcexe->partial == NULL ? 0 : funcexe->partial->pt_argc)) {
- argp = skipwhite(argp + 1); // skip the '(' or ','
+ argp = (char_u *)skipwhite((char *)argp + 1); // skip the '(' or ','
if (*argp == ')' || *argp == ',' || *argp == NUL) {
break;
}
- if (eval1(&argp, &argvars[argcount], funcexe->evaluate) == FAIL) {
+ if (eval1((char **)&argp, &argvars[argcount], funcexe->evaluate) == FAIL) {
ret = FAIL;
break;
}
@@ -455,7 +454,7 @@ int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, func
((typval_T **)funcargs.ga_data)[funcargs.ga_len++] = &argvars[i];
}
}
- ret = call_func(name, len, rettv, argcount, argvars, funcexe);
+ ret = call_func((char *)name, len, rettv, argcount, argvars, funcexe);
funcargs.ga_len -= i;
} else if (!aborting()) {
@@ -470,7 +469,7 @@ int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, func
tv_clear(&argvars[argcount]);
}
- *arg = skipwhite(argp);
+ *arg = (char_u *)skipwhite((char *)argp);
return ret;
}
@@ -516,22 +515,22 @@ static char_u *fname_trans_sid(const char_u *const name, char_u *const fname_buf
if (llen > 0) {
fname_buf[0] = K_SPECIAL;
fname_buf[1] = KS_EXTRA;
- fname_buf[2] = (int)KE_SNR;
+ 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, FLEN_FIXED + 1 - i, "%" PRId64 "_",
+ snprintf((char *)fname_buf + i, (size_t)(FLEN_FIXED + 1 - i), "%" PRId64 "_",
(int64_t)current_sctx.sc_sid);
i = (int)STRLEN(fname_buf);
}
}
- if (i + STRLEN(name + llen) < FLEN_FIXED) {
+ if ((size_t)i + STRLEN(name + llen) < FLEN_FIXED) {
STRCPY(fname_buf + i, name + llen);
fname = fname_buf;
} else {
- fname = xmalloc(i + STRLEN(name + llen) + 1);
+ fname = xmalloc((size_t)i + STRLEN(name + llen) + 1);
*tofree = fname;
memmove(fname, fname_buf, (size_t)i);
STRCPY(fname + i, name + llen);
@@ -544,23 +543,20 @@ static char_u *fname_trans_sid(const char_u *const name, char_u *const fname_buf
}
/// Find a function by name, return pointer to it in ufuncs.
-/// @return NULL for unknown function.
+///
+/// @return NULL for unknown function.
ufunc_T *find_func(const char_u *name)
{
- hashitem_T *hi;
-
- hi = hash_find(&func_hashtab, name);
+ hashitem_T *hi = hash_find(&func_hashtab, (char *)name);
if (!HASHITEM_EMPTY(hi)) {
return HI2UF(hi);
}
return NULL;
}
-/*
- * Copy the function name of "fp" to buffer "buf".
- * "buf" must be able to hold the function name plus three bytes.
- * Takes care of script-local function names.
- */
+/// Copy the function name of "fp" to buffer "buf".
+/// "buf" must be able to hold the function name plus three bytes.
+/// Takes care of script-local function names.
static void cat_func_name(char_u *buf, ufunc_T *fp)
{
if (fp->uf_name[0] == K_SPECIAL) {
@@ -571,9 +567,7 @@ static void cat_func_name(char_u *buf, ufunc_T *fp)
}
}
-/*
- * Add a number variable "name" to dict "dp" with value "nr".
- */
+/// Add a number variable "name" to dict "dp" with value "nr".
static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)
{
#ifndef __clang_analyzer__
@@ -586,7 +580,7 @@ static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)
v->di_tv.vval.v_number = nr;
}
-// Free "fc"
+/// Free "fc"
static void free_funccal(funccall_T *fc)
{
for (int i = 0; i < fc->fc_funcs.ga_len; i++) {
@@ -606,9 +600,9 @@ static void free_funccal(funccall_T *fc)
xfree(fc);
}
-// Free "fc" and what it contains.
-// Can be called only when "fc" is kept beyond the period of it called,
-// i.e. after cleanup_function_call(fc).
+/// Free "fc" and what it contains.
+/// Can be called only when "fc" is kept beyond the period of it called,
+/// i.e. after cleanup_function_call(fc).
static void free_funccal_contents(funccall_T *fc)
{
// Free all l: variables.
@@ -728,7 +722,7 @@ static void funccal_unref(funccall_T *fc, ufunc_T *fp, bool force)
/// @return true if the entry was deleted, false if it wasn't found.
static bool func_remove(ufunc_T *fp)
{
- hashitem_T *hi = hash_find(&func_hashtab, UF2HIKEY(fp));
+ hashitem_T *hi = hash_find(&func_hashtab, (char *)UF2HIKEY(fp));
if (!HASHITEM_EMPTY(hi)) {
hash_remove(&func_hashtab, hi);
@@ -757,7 +751,7 @@ static void func_clear_items(ufunc_T *fp)
/// Free all things that a function contains. Does not free the function
/// itself, use func_free() for that.
///
-/// param[in] force When true, we are exiting.
+/// @param[in] force When true, we are exiting.
static void func_clear(ufunc_T *fp, bool force)
{
if (fp->uf_cleared) {
@@ -773,7 +767,7 @@ static void func_clear(ufunc_T *fp, bool force)
/// Free a function and remove it from the list of functions. Does not free
/// what a function contains, call func_clear() first.
///
-/// param[in] fp The function to free.
+/// @param[in] fp The function to free.
static void func_free(ufunc_T *fp)
{
// only remove it when not done already, otherwise we would remove a newer
@@ -786,7 +780,7 @@ static void func_free(ufunc_T *fp)
/// Free all things that a function contains and free the function itself.
///
-/// param[in] force When true, we are exiting.
+/// @param[in] force When true, we are exiting.
static void func_clear_free(ufunc_T *fp, bool force)
{
func_clear(fp, force);
@@ -795,13 +789,13 @@ static void func_clear_free(ufunc_T *fp, bool force)
/// Call a user function
///
-/// @param fp Function to call.
-/// @param[in] argcount Number of arguments.
-/// @param argvars Arguments.
-/// @param[out] rettv Return value.
-/// @param[in] firstline First line of range.
-/// @param[in] lastline Last line of range.
-/// @param selfdict Dictionary for "self" for dictionary functions.
+/// @param fp Function to call.
+/// @param[in] argcount Number of arguments.
+/// @param argvars Arguments.
+/// @param[out] rettv Return value.
+/// @param[in] firstline First line of range.
+/// @param[in] lastline Last line of range.
+/// @param selfdict Dictionary for "self" for dictionary functions.
void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv,
linenr_T firstline, linenr_T lastline, dict_T *selfdict)
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
@@ -944,7 +938,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
default_expr = ((char_u **)(fp->uf_def_args.ga_data))
[ai + fp->uf_def_args.ga_len];
- if (eval1(&default_expr, &def_rettv, true) == FAIL) {
+ if (eval1((char **)&default_expr, &def_rettv, true) == FAIL) {
default_arg_err = true;
break;
}
@@ -997,7 +991,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
// Don't redraw while executing the function.
RedrawingDisabled++;
- save_sourcing_name = sourcing_name;
+ save_sourcing_name = (char_u *)sourcing_name;
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 1;
@@ -1017,7 +1011,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
{
if (save_sourcing_name != NULL
&& STRNCMP(save_sourcing_name, "function ", 9) == 0) {
- vim_snprintf((char *)sourcing_name,
+ vim_snprintf(sourcing_name,
len,
"%s[%" PRId64 "]..",
save_sourcing_name,
@@ -1025,7 +1019,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
} else {
STRCPY(sourcing_name, "function ");
}
- cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
+ cat_func_name((char_u *)sourcing_name + STRLEN(sourcing_name), fp);
if (p_verbose >= 12) {
++no_wait_return;
@@ -1048,9 +1042,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
if (tofree != NULL) {
char *s = tofree;
char buf[MSG_BUF_LEN];
- if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) {
- trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN,
- sizeof(buf));
+ if (vim_strsize(s) > MSG_BUF_CLEN) {
+ trunc_string(s, buf, MSG_BUF_CLEN, sizeof(buf));
s = buf;
}
msg_puts(s);
@@ -1106,7 +1099,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
// A Lambda always has the command "return {expr}". It is much faster
// to evaluate {expr} directly.
ex_nesting_level++;
- (void)eval1(&p, rettv, true);
+ (void)eval1((char **)&p, rettv, true);
ex_nesting_level--;
} else {
// call do_cmdline() to execute the lines
@@ -1153,14 +1146,14 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
smsg(_("%s returning #%" PRId64 ""),
sourcing_name, (int64_t)fc->rettv->vval.v_number);
} else {
- char_u buf[MSG_BUF_LEN];
+ char buf[MSG_BUF_LEN];
// The value may be very long. Skip the middle part, so that we
// have some idea how it starts and ends. smsg() would always
// truncate it at the end. Don't want errors such as E724 here.
emsg_off++;
- char_u *s = (char_u *)encode_tv2string(fc->rettv, NULL);
- char_u *tofree = s;
+ char *s = encode_tv2string(fc->rettv, NULL);
+ char *tofree = s;
emsg_off--;
if (s != NULL) {
if (vim_strsize(s) > MSG_BUF_CLEN) {
@@ -1178,7 +1171,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
}
xfree(sourcing_name);
- sourcing_name = save_sourcing_name;
+ sourcing_name = (char *)save_sourcing_name;
sourcing_lnum = save_sourcing_lnum;
current_sctx = save_current_sctx;
if (do_profiling_yes) {
@@ -1230,8 +1223,8 @@ static bool func_name_refcount(char_u *name)
static funccal_entry_T *funccal_stack = NULL;
-// Save the current function call pointer, and set it to NULL.
-// Used when executing autocommands and for ":source".
+/// Save the current function call pointer, and set it to NULL.
+/// Used when executing autocommands and for ":source".
void save_funccal(funccal_entry_T *entry)
{
entry->top_funccal = current_funccal;
@@ -1373,7 +1366,7 @@ int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict
funcexe.evaluate = true;
funcexe.partial = partial;
funcexe.selfdict = selfdict;
- r = call_func(name, -1, rettv, argc, argv, &funcexe);
+ r = call_func((char *)name, -1, rettv, argc, argv, &funcexe);
func_call_skip_call:
// Free the arguments.
@@ -1384,8 +1377,8 @@ func_call_skip_call:
return r;
}
-// Give an error message for the result of a function.
-// Nothing if "error" is FCERR_NONE.
+/// Give an error message for the result of a function.
+/// Nothing if "error" is FCERR_NONE.
static void user_func_error(int error, const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
@@ -1425,7 +1418,7 @@ static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int
{
if (basetv != NULL) {
// Method call: base->Method()
- memmove(&new_argvars[1], *argvars, sizeof(typval_T) * (*argcount));
+ memmove(&new_argvars[1], *argvars, sizeof(typval_T) * (size_t)(*argcount));
new_argvars[0] = *basetv;
(*argcount)++;
*argvars = new_argvars;
@@ -1445,8 +1438,8 @@ static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int
/// @return FAIL if function cannot be called, else OK (even if an error
/// occurred while executing the function! Set `msg_list` to capture
/// the error, see do_cmdline()).
-int call_func(const char_u *funcname, int len, typval_T *rettv, int argcount_in,
- typval_T *argvars_in, funcexe_T *funcexe)
+int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in,
+ funcexe_T *funcexe)
FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
{
int ret = FAIL;
@@ -1478,7 +1471,7 @@ int call_func(const char_u *funcname, int len, typval_T *rettv, int argcount_in,
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(funcname, len);
+ name = vim_strnsave((char_u *)funcname, (size_t)len);
fname = fname_trans_sid(name, fname_buf, &tofree, &error);
}
@@ -1525,11 +1518,11 @@ int call_func(const char_u *funcname, int len, typval_T *rettv, int argcount_in,
if (len > 0) {
error = ERROR_NONE;
argv_add_base(funcexe->basetv, &argvars, &argcount, argv, &argv_base);
- nlua_typval_call((const char *)funcname, len, argvars, argcount, rettv);
+ nlua_typval_call(funcname, (size_t)len, argvars, argcount, rettv);
} else {
// v:lua was called directly; show its name in the emsg
XFREE_CLEAR(name);
- funcname = (const char_u *)"v:lua";
+ funcname = "v:lua";
}
} else if (fp != NULL || !builtin_function((const char *)rfname, -1)) {
// User defined function.
@@ -1539,7 +1532,7 @@ int call_func(const char_u *funcname, int len, typval_T *rettv, int argcount_in,
// Trigger FuncUndefined event, may load the function.
if (fp == NULL
- && apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, true, NULL)
+ && apply_autocmds(EVENT_FUNCUNDEFINED, (char *)rfname, (char *)rfname, true, NULL)
&& !aborting()) {
// executed an autocommand, search for the function again
fp = find_func(rfname);
@@ -1611,7 +1604,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 : funcname);
+ user_func_error(error, (name != NULL) ? name : (char_u *)funcname);
}
// clear the copies made from the partial
@@ -1713,10 +1706,10 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp,
// Check for hard coded <SNR>: already translated function ID (from a user
// command).
if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
- && (*pp)[2] == (int)KE_SNR) {
+ && (*pp)[2] == KE_SNR) {
*pp += 3;
len = get_id_len((const char **)pp) + 3;
- return (char_u *)xmemdupz(start, len);
+ return (char_u *)xmemdupz(start, (size_t)len);
}
// A name starting with "<SID>" or "<SNR>" is local to a script. But
@@ -1727,8 +1720,8 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp,
}
// Note that TFN_ flags use the same values as GLV_ flags.
- end = get_lval((char_u *)start, NULL, &lv, false, skip, flags | GLV_READ_ONLY,
- lead > 2 ? 0 : FNE_CHECK_START);
+ end = (char_u *)get_lval((char *)start, NULL, &lv, false, skip, flags | GLV_READ_ONLY,
+ lead > 2 ? 0 : FNE_CHECK_START);
if (end == start) {
if (!skip) {
emsg(_("E129: Function name required"));
@@ -1746,7 +1739,7 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp,
semsg(_(e_invarg2), start);
}
} else {
- *pp = (char_u *)find_name_end(start, NULL, NULL, FNE_INCL_BR);
+ *pp = (char_u *)find_name_end((char *)start, NULL, NULL, FNE_INCL_BR);
}
goto theend;
}
@@ -1754,26 +1747,26 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp,
if (lv.ll_tv != NULL) {
if (fdp != NULL) {
fdp->fd_dict = lv.ll_dict;
- fdp->fd_newkey = lv.ll_newkey;
+ fdp->fd_newkey = (char_u *)lv.ll_newkey;
lv.ll_newkey = NULL;
fdp->fd_di = lv.ll_di;
}
if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) {
- name = vim_strsave(lv.ll_tv->vval.v_string);
+ name = vim_strsave((char_u *)lv.ll_tv->vval.v_string);
*pp = (char_u *)end;
} else if (lv.ll_tv->v_type == VAR_PARTIAL
&& lv.ll_tv->vval.v_partial != NULL) {
if (is_luafunc(lv.ll_tv->vval.v_partial) && *end == '.') {
- len = check_luafunc_name((const char *)end+1, true);
+ len = check_luafunc_name((const char *)end + 1, true);
if (len == 0) {
semsg(e_invexpr2, "v:lua");
goto theend;
}
- name = xmallocz(len);
- memcpy(name, end+1, len);
- *pp = (char_u *)end+1+len;
+ name = xmallocz((size_t)len);
+ memcpy(name, end + 1, (size_t)len);
+ *pp = (char_u *)end + 1 + len;
} else {
- name = vim_strsave(partial_name(lv.ll_tv->vval.v_partial));
+ name = vim_strsave((char_u *)partial_name(lv.ll_tv->vval.v_partial));
*pp = (char_u *)end;
}
if (partial != NULL) {
@@ -1821,7 +1814,7 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp,
// Change "<SNR>" to the byte sequence.
name[0] = K_SPECIAL;
name[1] = KS_EXTRA;
- name[2] = (int)KE_SNR;
+ name[2] = KE_SNR;
memmove(name + 3, name + 5, strlen((char *)name + 5) + 1);
}
goto theend;
@@ -1864,12 +1857,11 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp,
emsg(_(e_usingsid));
goto theend;
}
- sid_buf_len = snprintf(sid_buf, sizeof(sid_buf),
- "%" PRIdSCID "_", current_sctx.sc_sid);
- lead += sid_buf_len;
+ sid_buf_len =
+ (size_t)snprintf(sid_buf, sizeof(sid_buf), "%" PRIdSCID "_", current_sctx.sc_sid);
+ lead += (int)sid_buf_len;
}
- } else if (!(flags & TFN_INT)
- && builtin_function(lv.ll_name, lv.ll_name_len)) {
+ } else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, (int)lv.ll_name_len)) {
semsg(_("E128: Function name must start with a capital or \"s:\": %s"),
start);
goto theend;
@@ -1884,16 +1876,16 @@ char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp,
}
}
- name = xmalloc(len + lead + 1);
+ name = xmalloc((size_t)len + (size_t)lead + 1);
if (!skip && lead > 0) {
name[0] = K_SPECIAL;
name[1] = KS_EXTRA;
- name[2] = (int)KE_SNR;
+ name[2] = KE_SNR;
if (sid_buf_len > 0) { // If it's "<SID>"
memcpy(name + 3, sid_buf, sid_buf_len);
}
}
- memmove(name + lead, lv.ll_name, len);
+ memmove(name + lead, lv.ll_name, (size_t)len);
name[lead + len] = NUL;
*pp = (char_u *)end;
@@ -1902,14 +1894,12 @@ theend:
return name;
}
-/*
- * ":function"
- */
+/// ":function"
void ex_function(exarg_T *eap)
{
char_u *theline;
char_u *line_to_free = NULL;
- int c;
+ char_u c;
int saved_did_emsg;
bool saved_wait_return = need_wait_return;
char_u *name = NULL;
@@ -1959,7 +1949,7 @@ void ex_function(exarg_T *eap)
}
}
}
- eap->nextcmd = check_nextcmd(eap->arg);
+ eap->nextcmd = (char *)check_nextcmd((char_u *)eap->arg);
return;
}
@@ -1967,7 +1957,7 @@ void ex_function(exarg_T *eap)
* ":function /pat": list functions matching pattern.
*/
if (*eap->arg == '/') {
- p = skip_regexp(eap->arg + 1, '/', TRUE, NULL);
+ p = skip_regexp((char_u *)eap->arg + 1, '/', true, NULL);
if (!eap->skip) {
regmatch_T regmatch;
@@ -1984,7 +1974,7 @@ void ex_function(exarg_T *eap)
--todo;
fp = HI2UF(hi);
if (!isdigit(*fp->uf_name)
- && vim_regexec(&regmatch, fp->uf_name, 0)) {
+ && vim_regexec(&regmatch, (char *)fp->uf_name, 0)) {
list_func_head(fp, false, false);
}
}
@@ -1995,7 +1985,7 @@ void ex_function(exarg_T *eap)
if (*p == '/') {
++p;
}
- eap->nextcmd = check_nextcmd(p);
+ eap->nextcmd = (char *)check_nextcmd(p);
return;
}
@@ -2013,9 +2003,9 @@ 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 = eap->arg;
+ p = (char_u *)eap->arg;
name = trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL);
- paren = (vim_strchr(p, '(') != NULL);
+ paren = (vim_strchr((char *)p, '(') != NULL);
if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) {
/*
* Return on an invalid expression in braces, unless the expression
@@ -2045,11 +2035,11 @@ void ex_function(exarg_T *eap)
// - exclude line numbers from function body
//
if (!paren) {
- if (!ends_excmd(*skipwhite(p))) {
+ if (!ends_excmd(*skipwhite((char *)p))) {
emsg(_(e_trailing));
goto ret_free;
}
- eap->nextcmd = check_nextcmd(p);
+ eap->nextcmd = (char *)check_nextcmd(p);
if (eap->nextcmd != NULL) {
*p = NUL;
}
@@ -2089,18 +2079,18 @@ void ex_function(exarg_T *eap)
/*
* ":function name(arg1, arg2)" Define function.
*/
- p = skipwhite(p);
+ p = (char_u *)skipwhite((char *)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(p, '(') != NULL) {
- p = vim_strchr(p, '(');
+ if (vim_strchr((char *)p, '(') != NULL) {
+ p = (char_u *)vim_strchr((char *)p, '(');
}
}
- p = skipwhite(p + 1);
+ p = (char_u *)skipwhite((char *)p + 1);
ga_init(&newargs, (int)sizeof(char_u *), 3);
ga_init(&newlines, (int)sizeof(char_u *), 3);
@@ -2141,7 +2131,7 @@ void ex_function(exarg_T *eap)
// find extra arguments "range", "dict", "abort" and "closure"
for (;;) {
- p = skipwhite(p);
+ p = (char_u *)skipwhite((char *)p);
if (STRNCMP(p, "range", 5) == 0) {
flags |= FC_RANGE;
p += 5;
@@ -2213,7 +2203,7 @@ void ex_function(exarg_T *eap)
if (line_arg != NULL) {
// Use eap->arg, split up in parts by line breaks.
theline = line_arg;
- p = vim_strchr(theline, '\n');
+ p = (char_u *)vim_strchr((char *)theline, '\n');
if (p == NULL) {
line_arg += STRLEN(line_arg);
} else {
@@ -2225,7 +2215,7 @@ void ex_function(exarg_T *eap)
if (eap->getline == NULL) {
theline = getcmdline(':', 0L, indent, do_concat);
} else {
- theline = eap->getline(':', eap->cookie, indent, do_concat);
+ theline = (char_u *)eap->getline(':', eap->cookie, indent, do_concat);
}
line_to_free = theline;
}
@@ -2255,13 +2245,13 @@ void ex_function(exarg_T *eap)
// * ":python <<EOF" and "EOF"
// * ":let {var-name} =<< [trim] {marker}" and "{marker}"
if (heredoc_trimmed == NULL
- || (is_heredoc && skipwhite(theline) == theline)
+ || (is_heredoc && (char_u *)skipwhite((char *)theline) == theline)
|| STRNCMP(theline, heredoc_trimmed,
STRLEN(heredoc_trimmed)) == 0) {
if (heredoc_trimmed == NULL) {
p = theline;
} else if (is_heredoc) {
- p = skipwhite(theline) == theline
+ p = (char_u *)skipwhite((char *)theline) == theline
? theline : theline + STRLEN(heredoc_trimmed);
} else {
p = theline + STRLEN(heredoc_trimmed);
@@ -2275,18 +2265,17 @@ void ex_function(exarg_T *eap)
}
} else {
// skip ':' and blanks
- for (p = theline; ascii_iswhite(*p) || *p == ':'; p++) {
- }
+ for (p = theline; ascii_iswhite(*p) || *p == ':'; p++) {}
// Check for "endfunction".
- if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) {
+ if (checkforcmd((char **)&p, "endfunction", 4) && nesting-- == 0) {
if (*p == '!') {
p++;
}
char_u *nextcmd = NULL;
if (*p == '|') {
nextcmd = p + 1;
- } else if (line_arg != NULL && *skipwhite(line_arg) != NUL) {
+ } else if (line_arg != NULL && *skipwhite((char *)line_arg) != NUL) {
nextcmd = line_arg;
} else if (*p != NUL && *p != '"' && p_verbose > 0) {
give_warning2((char_u *)_("W22: Text found after :endfunction: %s"),
@@ -2296,10 +2285,10 @@ void ex_function(exarg_T *eap)
// Another command follows. If the line came from "eap" we
// can simply point into it, otherwise we need to change
// "eap->cmdlinep".
- eap->nextcmd = nextcmd;
+ eap->nextcmd = (char *)nextcmd;
if (line_to_free != NULL) {
xfree(*eap->cmdlinep);
- *eap->cmdlinep = line_to_free;
+ *eap->cmdlinep = (char *)line_to_free;
line_to_free = NULL;
}
}
@@ -2318,20 +2307,20 @@ void ex_function(exarg_T *eap)
}
// Check for defining a function inside this function.
- if (checkforcmd(&p, "function", 2)) {
+ if (checkforcmd((char **)&p, "function", 2)) {
if (*p == '!') {
- p = skipwhite(p + 1);
+ p = (char_u *)skipwhite((char *)p + 1);
}
p += eval_fname_script((const char *)p);
xfree(trans_function_name(&p, true, 0, NULL, NULL));
- if (*skipwhite(p) == '(') {
+ if (*skipwhite((char *)p) == '(') {
nesting++;
indent += 2;
}
}
// Check for ":append", ":change", ":insert".
- p = skip_range(p, NULL);
+ p = (char_u *)skip_range((char *)p, NULL);
if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
|| (p[0] == 'c'
&& (!ASCII_ISALPHA(p[1])
@@ -2347,7 +2336,7 @@ void ex_function(exarg_T *eap)
}
// heredoc: Check for ":python <<EOF", ":lua <<EOF", etc.
- arg = skipwhite(skiptowhite(p));
+ arg = (char_u *)skipwhite((char *)skiptowhite(p));
if (arg[0] == '<' && arg[1] == '<'
&& ((p[0] == 'p' && p[1] == 'y'
&& (!ASCII_ISALNUM(p[2]) || p[2] == 't'
@@ -2364,7 +2353,7 @@ 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 = skipwhite(arg + 2);
+ p = (char_u *)skipwhite((char *)arg + 2);
if (*p == NUL) {
skip_until = vim_strsave((char_u *)".");
} else {
@@ -2374,12 +2363,12 @@ void ex_function(exarg_T *eap)
// Check for ":let v =<< [trim] EOF"
// and ":let [a, b] =<< [trim] EOF"
- arg = skipwhite(skiptowhite(p));
+ arg = (char_u *)skipwhite((char *)skiptowhite(p));
if (*arg == '[') {
- arg = vim_strchr(arg, ']');
+ arg = (char_u *)vim_strchr((char *)arg, ']');
}
if (arg != NULL) {
- arg = skipwhite(skiptowhite(arg));
+ arg = (char_u *)skipwhite((char *)skiptowhite(arg));
if (arg[0] == '='
&& arg[1] == '<'
&& arg[2] == '<'
@@ -2387,14 +2376,14 @@ void ex_function(exarg_T *eap)
&& p[1] == 'e'
&& (!ASCII_ISALNUM(p[2])
|| (p[2] == 't' && !ASCII_ISALNUM(p[3]))))) {
- p = skipwhite(arg + 3);
+ p = (char_u *)skipwhite((char *)arg + 3);
if (STRNCMP(p, "trim", 4) == 0) {
// Ignore leading white space.
- p = skipwhite(p + 4);
+ p = (char_u *)skipwhite((char *)p + 4);
heredoc_trimmed =
- vim_strnsave(theline, skipwhite(theline) - theline);
+ vim_strnsave(theline, (size_t)((char_u *)skipwhite((char *)theline) - theline));
}
- skip_until = vim_strnsave(p, skiptowhite(p) - p);
+ skip_until = vim_strnsave(p, (size_t)(skiptowhite(p) - p));
do_concat = false;
is_heredoc = true;
}
@@ -2402,7 +2391,7 @@ void ex_function(exarg_T *eap)
}
// Add the line to the function.
- ga_grow(&newlines, 1 + sourcing_lnum_off);
+ ga_grow(&newlines, 1 + (int)sourcing_lnum_off);
// Copy the line to newly allocated memory. get_one_sourceline()
// allocates 250 bytes per line, this saves 80% on average. The cost
@@ -2497,7 +2486,7 @@ void ex_function(exarg_T *eap)
}
if (fp == NULL) {
- if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) {
+ if (fudi.fd_dict == NULL && vim_strchr((char *)name, AUTOLOAD_CHAR) != NULL) {
int slen, plen;
char_u *scriptname;
@@ -2505,10 +2494,10 @@ void ex_function(exarg_T *eap)
int j = FAIL;
if (sourcing_name != NULL) {
scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name));
- p = vim_strchr(scriptname, '/');
+ p = (char_u *)vim_strchr((char *)scriptname, '/');
plen = (int)STRLEN(p);
slen = (int)STRLEN(sourcing_name);
- if (slen > plen && fnamecmp(p,
+ if (slen > plen && FNAMECMP(p,
sourcing_name + slen - plen) == 0) {
j = OK;
}
@@ -2537,7 +2526,7 @@ 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 = vim_strsave(name);
+ fudi.fd_di->di_tv.vval.v_string = (char *)vim_strsave(name);
// behave like "dict" was used
flags |= FC_DICT;
@@ -2546,7 +2535,7 @@ void ex_function(exarg_T *eap)
// insert the new function in the function list
STRCPY(fp->uf_name, name);
if (overwrite) {
- hi = hash_find(&func_hashtab, name);
+ hi = hash_find(&func_hashtab, (char *)name);
hi->hi_key = UF2HIKEY(fp);
} else if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) {
xfree(fp);
@@ -2573,6 +2562,7 @@ void ex_function(exarg_T *eap)
fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx;
fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
+ nlua_set_sctx(&fp->uf_script_ctx);
goto ret_free;
@@ -2592,13 +2582,11 @@ ret_free:
if (show_block) {
ui_ext_cmdline_block_leave();
}
-} // NOLINT(readability/fn_size)
+}
-/*
- * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
- * Return 2 if "p" starts with "s:".
- * Return 0 otherwise.
- */
+/// @return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
+/// 2 if "p" starts with "s:".
+/// 0 otherwise.
int eval_fname_script(const char *const p)
{
// Use mb_strnicmp() because in Turkish comparing the "I" may not work with
@@ -2624,10 +2612,10 @@ bool translated_function_exists(const char *name)
/// Check whether function with the given name exists
///
-/// @param[in] name Function name.
-/// @param[in] no_deref Whether to dereference a Funcref.
+/// @param[in] name Function name.
+/// @param[in] no_deref Whether to dereference a Funcref.
///
-/// @return True if it exists, false otherwise.
+/// @return true if it exists, false otherwise.
bool function_exists(const char *const name, bool no_deref)
{
const char_u *nm = (const char_u *)name;
@@ -2639,7 +2627,7 @@ bool function_exists(const char *const name, bool no_deref)
}
char *const p = (char *)trans_function_name((char_u **)&nm, false, flag, NULL,
NULL);
- nm = skipwhite(nm);
+ nm = (char_u *)skipwhite((char *)nm);
// Only accept "funcname", "funcname ", "funcname (..." and
// "funcname(...", not "funcname!...".
@@ -2650,11 +2638,9 @@ bool function_exists(const char *const name, bool no_deref)
return n;
}
-/*
- * Function given to ExpandGeneric() to obtain the list of user defined
- * function names.
- */
-char_u *get_user_func_name(expand_T *xp, int idx)
+/// Function given to ExpandGeneric() to obtain the list of user defined
+/// function names.
+char *get_user_func_name(expand_T *xp, int idx)
{
static size_t done;
static hashitem_T *hi;
@@ -2676,11 +2662,11 @@ char_u *get_user_func_name(expand_T *xp, int idx)
if ((fp->uf_flags & FC_DICT)
|| STRNCMP(fp->uf_name, "<lambda>", 8) == 0) {
- return (char_u *)""; // don't show dict and lambda functions
+ return ""; // don't show dict and lambda functions
}
if (STRLEN(fp->uf_name) + 4 >= IOSIZE) {
- return fp->uf_name; // Prevent overflow.
+ return (char *)fp->uf_name; // Prevent overflow.
}
cat_func_name(IObuff, fp);
@@ -2690,7 +2676,7 @@ char_u *get_user_func_name(expand_T *xp, int idx)
STRCAT(IObuff, ")");
}
}
- return IObuff;
+ return (char *)IObuff;
}
return NULL;
}
@@ -2703,7 +2689,7 @@ void ex_delfunction(exarg_T *eap)
char_u *name;
funcdict_T fudi;
- p = eap->arg;
+ p = (char_u *)eap->arg;
name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
xfree(fudi.fd_newkey);
if (name == NULL) {
@@ -2712,12 +2698,12 @@ void ex_delfunction(exarg_T *eap)
}
return;
}
- if (!ends_excmd(*skipwhite(p))) {
+ if (!ends_excmd(*skipwhite((char *)p))) {
xfree(name);
emsg(_(e_trailing));
return;
}
- eap->nextcmd = check_nextcmd(p);
+ eap->nextcmd = (char *)check_nextcmd(p);
if (eap->nextcmd != NULL) {
*p = NUL;
}
@@ -2770,10 +2756,8 @@ void ex_delfunction(exarg_T *eap)
}
}
-/*
- * Unreference a Function: decrement the reference count and free it when it
- * becomes zero.
- */
+/// Unreference a Function: decrement the reference count and free it when it
+/// becomes zero.
void func_unref(char_u *name)
{
ufunc_T *fp = NULL;
@@ -2867,12 +2851,10 @@ static int can_free_funccal(funccall_T *fc, int copyID)
&& fc->fc_copyID != copyID;
}
-/*
- * ":return [expr]"
- */
+/// ":return [expr]"
void ex_return(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = (char_u *)eap->arg;
typval_T rettv;
int returning = FALSE;
@@ -2887,7 +2869,7 @@ void ex_return(exarg_T *eap)
eap->nextcmd = NULL;
if ((*arg != NUL && *arg != '|' && *arg != '\n')
- && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) {
+ && eval0((char *)arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) {
if (!eap->skip) {
returning = do_return(eap, false, true, &rettv);
} else {
@@ -2910,7 +2892,7 @@ void ex_return(exarg_T *eap)
if (returning) {
eap->nextcmd = NULL;
} else if (eap->nextcmd == NULL) { // no argument
- eap->nextcmd = check_nextcmd(arg);
+ eap->nextcmd = (char *)check_nextcmd(arg);
}
if (eap->skip) {
@@ -2920,12 +2902,10 @@ void ex_return(exarg_T *eap)
// TODO(ZyX-I): move to eval/ex_cmds
-/*
- * ":1,25call func(arg1, arg2)" function call.
- */
+/// ":1,25call func(arg1, arg2)" function call.
void ex_call(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = (char_u *)eap->arg;
char_u *startarg;
char_u *name;
char_u *tofree;
@@ -2974,7 +2954,7 @@ void ex_call(exarg_T *eap)
// Skip white space to allow ":call func ()". Not good, but required for
// backward compatibility.
- startarg = skipwhite(arg);
+ startarg = (char_u *)skipwhite((char *)arg);
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this.
if (*startarg != '(') {
@@ -3011,7 +2991,7 @@ void ex_call(exarg_T *eap)
// Handle a function returning a Funcref, Dictionary or List.
if (handle_subscript((const char **)&arg, &rettv, true, true,
- (const char_u *)name, (const char_u **)&name)
+ (const char *)name, (const char **)&name)
== FAIL) {
failed = true;
break;
@@ -3031,16 +3011,17 @@ void ex_call(exarg_T *eap)
}
}
- // When inside :try we need to check for following "| catch".
- if (!failed || eap->cstack->cs_trylevel > 0) {
+ // 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)) {
// Check for trailing illegal characters and a following command.
if (!ends_excmd(*arg)) {
- if (!failed) {
+ if (!failed && !aborting()) {
emsg_severe = true;
emsg(_(e_trailing));
}
} else {
- eap->nextcmd = check_nextcmd(arg);
+ eap->nextcmd = (char *)check_nextcmd(arg);
}
}
@@ -3049,14 +3030,16 @@ end:
xfree(tofree);
}
-/*
- * Return from a function. Possibly makes the return pending. Also called
- * for a pending return at the ":endtry" or after returning from an extra
- * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set
- * when called due to a ":return" command. "rettv" may point to a typval_T
- * with the return rettv. Returns TRUE when the return can be carried out,
- * FALSE when the return gets pending.
- */
+/// Return from a function. Possibly makes the return pending. Also called
+/// for a pending return at the ":endtry" or after returning from an extra
+/// do_cmdline(). "reanimate" is used in the latter case.
+///
+/// @param reanimate used after returning from an extra do_cmdline().
+/// @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.
int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
{
int idx;
@@ -3067,12 +3050,10 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
current_funccal->returned = false;
}
- //
// Cleanup (and deactivate) conditionals, but stop when a try conditional
// not in its finally clause (which then is to be executed next) is found.
// In this case, make the ":return" pending for execution at the ":endtry".
// Otherwise, return normally.
- //
idx = cleanup_conditionals(eap->cstack, 0, true);
if (idx >= 0) {
cstack->cs_pending[idx] = CSTP_RETURN;
@@ -3125,10 +3106,8 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
return idx < 0;
}
-/*
- * Generate a return command for producing the value of "rettv". The result
- * is an allocated string. Used by report_pending() for verbose messages.
- */
+/// 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_u *s = NULL;
@@ -3150,12 +3129,11 @@ char_u *get_return_cmd(void *rettv)
return vim_strsave(IObuff);
}
-/*
- * Get next function line.
- * Called by do_cmdline() to get the next line.
- * Returns allocated string, or NULL for end of function.
- */
-char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
+/// Get next function line.
+/// Called by do_cmdline() to get the next line.
+///
+/// @return allocated string, or NULL for end of function.
+char *get_func_line(int c, void *cookie, int indent, bool do_concat)
{
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
@@ -3202,13 +3180,11 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
fcp->dbg_tick = debug_tick;
}
- return retval;
+ return (char *)retval;
}
-/*
- * Return TRUE if the currently active function should be ended, because a
- * return was encountered or an error occurred. Used inside a ":while".
- */
+/// @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)
{
funccall_T *fcp = (funccall_T *)cookie;
@@ -3219,9 +3195,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;
@@ -3241,7 +3215,7 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv)
fp = rettv->vval.v_partial->pt_func;
} else {
fname = rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING
- ? rettv->vval.v_string
+ ? (char_u *)rettv->vval.v_string
: rettv->vval.v_partial->pt_name;
// Translate "s:func" to the stored function name.
fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
@@ -3258,7 +3232,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 = rettv->vval.v_string;
+ pt->pt_name = (char_u *)rettv->vval.v_string;
} else {
partial_T *ret_pt = rettv->vval.v_partial;
int i;
@@ -3274,7 +3248,7 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv)
func_ptr_ref(pt->pt_func);
}
if (ret_pt->pt_argc > 0) {
- size_t arg_size = sizeof(typval_T) * ret_pt->pt_argc;
+ size_t arg_size = sizeof(typval_T) * (size_t)ret_pt->pt_argc;
pt->pt_argv = (typval_T *)xmalloc(arg_size);
pt->pt_argc = ret_pt->pt_argc;
for (i = 0; i < pt->pt_argc; i++) {
@@ -3288,41 +3262,31 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv)
}
}
-/*
- * Return the name of the executed function.
- */
+/// @return the name of the executed function.
char_u *func_name(void *cookie)
{
return ((funccall_T *)cookie)->func->uf_name;
}
-/*
- * Return the address holding the next breakpoint line for a funccall cookie.
- */
+/// @return the address holding the next breakpoint line for a funccall cookie.
linenr_T *func_breakpoint(void *cookie)
{
return &((funccall_T *)cookie)->breakpoint;
}
-/*
- * Return the address holding the debug tick for a funccall cookie.
- */
+/// @return the address holding the debug tick for a funccall cookie.
int *func_dbg_tick(void *cookie)
{
return &((funccall_T *)cookie)->dbg_tick;
}
-/*
- * Return the nesting level for a funccall cookie.
- */
+/// @return the nesting level for a funccall cookie.
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;
@@ -3371,8 +3335,8 @@ funccall_T *get_funccal(void)
return funccal;
}
-/// Return the hashtable used for local variables in the current funccal.
-/// Return NULL if there is no current funccal.
+/// @return hashtable used for local variables in the current funccal or
+/// NULL if there is no current funccal.
hashtab_T *get_funccal_local_ht(void)
{
if (current_funccal == NULL) {
@@ -3381,8 +3345,8 @@ hashtab_T *get_funccal_local_ht(void)
return &get_funccal()->l_vars.dv_hashtab;
}
-/// Return the l: scope variable.
-/// Return NULL if there is no current funccal.
+/// @return the l: scope variable or
+/// NULL if there is no current funccal.
dictitem_T *get_funccal_local_var(void)
{
if (current_funccal == NULL) {
@@ -3391,8 +3355,8 @@ dictitem_T *get_funccal_local_var(void)
return (dictitem_T *)&get_funccal()->l_vars_var;
}
-/// Return the hashtable used for argument in the current funccal.
-/// Return NULL if there is no current funccal.
+/// @return the hashtable used for argument in the current funccal or
+/// NULL if there is no current funccal.
hashtab_T *get_funccal_args_ht(void)
{
if (current_funccal == NULL) {
@@ -3401,8 +3365,8 @@ hashtab_T *get_funccal_args_ht(void)
return &get_funccal()->l_avars.dv_hashtab;
}
-/// Return the a: scope variable.
-/// Return NULL if there is no current funccal.
+/// @return the a: scope variable or
+/// NULL if there is no current funccal.
dictitem_T *get_funccal_args_var(void)
{
if (current_funccal == NULL) {
@@ -3411,9 +3375,7 @@ dictitem_T *get_funccal_args_var(void)
return (dictitem_T *)&current_funccal->l_avars_var;
}
-/*
- * List function variables, if there is a function.
- */
+/// List function variables, if there is a function.
void list_func_vars(int *first)
{
if (current_funccal != NULL) {
@@ -3422,9 +3384,8 @@ void list_func_vars(int *first)
}
}
-/// If "ht" is the hashtable for local variables in the current funccal, return
-/// the dict that contains it.
-/// Otherwise return NULL.
+/// @return if "ht" is the hashtable for local variables in the current
+/// funccal, return the dict that contains it. Otherwise return NULL.
dict_T *get_current_funccal_dict(hashtab_T *ht)
{
if (current_funccal != NULL && ht == &current_funccal->l_vars.dv_hashtab) {
@@ -3450,7 +3411,7 @@ hashitem_T *find_hi_in_scoped_ht(const char *name, hashtab_T **pht)
while (current_funccal != NULL) {
hashtab_T *ht = find_var_ht(name, namelen, &varname);
if (ht != NULL && *varname != NUL) {
- hi = hash_find_len(ht, varname, namelen - (varname - name));
+ hi = hash_find_len(ht, varname, namelen - (size_t)(varname - name));
if (!HASHITEM_EMPTY(hi)) {
*pht = ht;
break;
@@ -3588,7 +3549,7 @@ bool set_ref_in_func_args(int copyID)
/// "list_stack" is used to add lists to be marked. Can be NULL.
/// "ht_stack" is used to add hashtabs to be marked. Can be NULL.
///
-/// @return true if setting references failed somehow.
+/// @return true if setting references failed somehow.
bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
{
ufunc_T *fp = fp_in;
@@ -3633,5 +3594,6 @@ char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state)
STRCPY(fp->uf_name, name);
hash_add(&func_hashtab, UF2HIKEY(fp));
+ // coverity[leaked_storage]
return fp->uf_name;
}