aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcangscop <cangscop@gmail.com>2019-07-27 03:13:29 +0200
committercangscop <cangscop@gmail.com>2019-07-27 16:25:33 +0200
commit0364e47ccb8705d48146f00d68506d5f9cefb0aa (patch)
treea3d527e3440f29b6babcc7a80cd43c77445f73cb /src
parent0b4123668af65b489e188dfb1041e664a4ee3915 (diff)
downloadrneovim-0364e47ccb8705d48146f00d68506d5f9cefb0aa.tar.gz
rneovim-0364e47ccb8705d48146f00d68506d5f9cefb0aa.tar.bz2
rneovim-0364e47ccb8705d48146f00d68506d5f9cefb0aa.zip
vim-patch:8.1.53 use typval_T in the caller of call_vim_function
Problem: unreliable types for complete function arguments Solution: fix argument type for functions w/ unreliable type conversion(Ozaki Kiichi) vim/vim#2993
Diffstat (limited to 'src')
-rw-r--r--src/nvim/edit.c19
-rw-r--r--src/nvim/eval.c74
-rw-r--r--src/nvim/ex_getln.c22
-rw-r--r--src/nvim/normal.c10
4 files changed, 54 insertions, 71 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 6355000175..22bcfb6d16 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -3682,14 +3682,19 @@ expand_by_function (
return;
// Call 'completefunc' to obtain the list of matches.
- const char_u *const args[2] = { (char_u *)"0", base };
+ typval_T args[3];
+ args[0].v_type = VAR_NUMBER;
+ args[1].v_type = VAR_STRING;
+ args[2].v_type = VAR_UNKNOWN;
+ args[0].vval.v_number = 0;
+ args[1].vval.v_string = base != NULL ? base : (char_u *)"";
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
- /* Call a function, which returns a list or dict. */
- if (call_vim_function(funcname, 2, args, FALSE, FALSE, &rettv) == OK) {
+ // Call a function, which returns a list or dict.
+ if (call_vim_function(funcname, 2, args, false, &rettv) == OK) {
switch (rettv.v_type) {
case VAR_LIST:
matchlist = rettv.vval.v_list;
@@ -4892,7 +4897,13 @@ static int ins_complete(int c, bool enable_pum)
return FAIL;
}
- const char_u *const args[2] = { (char_u *)"1", NULL };
+ typval_T args[3];
+ args[0].v_type = VAR_NUMBER;
+ args[1].v_type = VAR_STRING;
+ args[2].v_type = VAR_UNKNOWN;
+ args[0].vval.v_number = 1;
+ args[1].vval.v_string = (char_u *)"";
+
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 0b943cedc7..53a7187b7c 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1275,68 +1275,35 @@ int get_spellword(list_T *const list, const char **ret_word)
// Call some vim script function and return the result in "*rettv".
-// Uses argv[argc] for the function arguments. Only Number and String
-// arguments are currently supported.
+// Uses argv[argc-1] for the function arguments. argv[argc]
+// should have type VAR_UNKNOWN.
//
// Return OK or FAIL.
int call_vim_function(
const char_u *func,
int argc,
- const char_u *const *const argv,
- bool safe, // use the sandbox
- int str_arg_only, // all arguments are strings
+ typval_T *argv,
+ int safe, // use the sandbox
typval_T *rettv
)
{
- varnumber_T n;
- int len;
int doesrange;
void *save_funccalp = NULL;
int ret;
- typval_T *argvars = xmalloc((argc + 1) * sizeof(typval_T));
-
- for (int i = 0; i < argc; i++) {
- // Pass a NULL or empty argument as an empty string
- if (argv[i] == NULL || *argv[i] == NUL) {
- argvars[i].v_type = VAR_STRING;
- argvars[i].vval.v_string = (char_u *)"";
- continue;
- }
-
- if (str_arg_only) {
- len = 0;
- } else {
- // Recognize a number argument, the others must be strings. A dash
- // is a string too.
- vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
- if (len == 1 && *argv[i] == '-') {
- len = 0;
- }
- }
- if (len != 0 && len == (int)STRLEN(argv[i])) {
- argvars[i].v_type = VAR_NUMBER;
- argvars[i].vval.v_number = n;
- } else {
- argvars[i].v_type = VAR_STRING;
- argvars[i].vval.v_string = (char_u *)argv[i];
- }
- }
-
if (safe) {
save_funccalp = save_funccal();
++sandbox;
}
rettv->v_type = VAR_UNKNOWN; // tv_clear() uses this.
- ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, NULL,
+ ret = call_func(func, (int)STRLEN(func), rettv, argc, argv, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&doesrange, true, NULL, NULL);
if (safe) {
--sandbox;
restore_funccal(save_funccalp);
}
- xfree(argvars);
if (ret == FAIL) {
tv_clear(rettv);
@@ -1344,47 +1311,44 @@ int call_vim_function(
return ret;
}
-
/// Call Vim script function and return the result as a number
///
/// @param[in] func Function name.
/// @param[in] argc Number of arguments.
-/// @param[in] argv Array with string arguments.
+/// @param[in] argv Array with typval_T arguments.
/// @param[in] safe Use with sandbox.
///
/// @return -1 when calling function fails, result of function otherwise.
varnumber_T call_func_retnr(char_u *func, int argc,
- const char_u *const *const argv, int safe)
+ typval_T *argv, int safe)
{
typval_T rettv;
varnumber_T retval;
- /* All arguments are passed as strings, no conversion to number. */
- if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
+ if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) {
return -1;
-
+ }
retval = tv_get_number_chk(&rettv, NULL);
tv_clear(&rettv);
return retval;
}
-
/// Call Vim script function and return the result as a string
///
/// @param[in] func Function name.
/// @param[in] argc Number of arguments.
-/// @param[in] argv Array with string arguments.
+/// @param[in] argv Array with typval_T arguments.
/// @param[in] safe Use the sandbox.
///
/// @return [allocated] NULL when calling function fails, allocated string
/// otherwise.
char *call_func_retstr(const char *const func, int argc,
- const char_u *const *argv,
+ typval_T *argv,
bool safe)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
typval_T rettv;
// All arguments are passed as strings, no conversion to number.
- if (call_vim_function((const char_u *)func, argc, argv, safe, true, &rettv)
+ if (call_vim_function((const char_u *)func, argc, argv, safe, &rettv)
== FAIL) {
return NULL;
}
@@ -1393,24 +1357,24 @@ char *call_func_retstr(const char *const func, int argc,
tv_clear(&rettv);
return retval;
}
-
/// Call Vim script function and return the result as a List
///
/// @param[in] func Function name.
/// @param[in] argc Number of arguments.
-/// @param[in] argv Array with string arguments.
+/// @param[in] argv Array with typval_T arguments.
/// @param[in] safe Use the sandbox.
///
/// @return [allocated] NULL when calling function fails or return tv is not a
/// List, allocated List otherwise.
-void *call_func_retlist(char_u *func, int argc, const char_u *const *argv,
+void *call_func_retlist(char_u *func, int argc, typval_T *argv,
bool safe)
{
typval_T rettv;
- /* All arguments are passed as strings, no conversion to number. */
- if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
+ // All arguments are passed as strings, no conversion to number.
+ if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) {
return NULL;
+ }
if (rettv.v_type != VAR_LIST) {
tv_clear(&rettv);
@@ -23892,6 +23856,8 @@ bool eval_has_provider(const char *name)
static int has_python = -1;
static int has_python3 = -1;
static int has_ruby = -1;
+ typval_T args[1];
+ args[0].v_type = VAR_UNKNOWN;
if (strequal(name, "clipboard")) {
CHECK_PROVIDER(clipboard);
@@ -23906,7 +23872,7 @@ bool eval_has_provider(const char *name)
bool need_check_ruby = (has_ruby == -1);
CHECK_PROVIDER(ruby);
if (need_check_ruby && has_ruby == 1) {
- char *rubyhost = call_func_retstr("provider#ruby#Detect", 0, NULL, true);
+ char *rubyhost = call_func_retstr("provider#ruby#Detect", 0, args, true);
if (rubyhost) {
if (*rubyhost == NUL) {
// Invalid rubyhost executable. Gem is probably not installed.
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index b3c0d0a982..ec9f978416 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -200,7 +200,7 @@ static Array cmdline_block = ARRAY_DICT_INIT;
*/
typedef void *(*user_expand_func_T)(const char_u *,
int,
- const char_u * const *,
+ typval_T *,
bool);
static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
@@ -5051,8 +5051,8 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
expand_T *xp, int *num_file, char_u ***file)
{
char_u keep = 0;
- char_u num[50];
- char_u *args[3];
+ typval_T args[4];
+ char_u *pat = NULL;
int save_current_SID = current_SID;
void *ret;
struct cmdline_info save_ccline;
@@ -5067,10 +5067,14 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
ccline.cmdbuff[ccline.cmdlen] = 0;
}
- args[0] = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
- args[1] = xp->xp_line;
- sprintf((char *)num, "%d", xp->xp_col);
- args[2] = num;
+ pat = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
+ args[0].v_type = VAR_STRING;
+ args[1].v_type = VAR_STRING;
+ args[2].v_type = VAR_NUMBER;
+ args[3].v_type = VAR_UNKNOWN;
+ args[0].vval.v_string = pat;
+ args[1].vval.v_string = xp->xp_line;
+ args[2].vval.v_number = xp->xp_col;
/* Save the cmdline, we don't know what the function may do. */
save_ccline = ccline;
@@ -5080,7 +5084,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
ret = user_expand_func(xp->xp_arg,
3,
- (const char_u * const *)args,
+ args,
false);
ccline = save_ccline;
@@ -5088,7 +5092,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
if (ccline.cmdbuff != NULL)
ccline.cmdbuff[ccline.cmdlen] = keep;
- xfree(args[0]);
+ xfree(pat);
return ret;
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index d33c5d33bb..286159ac0f 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2096,13 +2096,15 @@ static void op_function(oparg_T *oap)
decl(&curbuf->b_op_end);
}
- const char_u *const argv[1] = {
- (const char_u *)(((const char *const[]) {
+ typval_T argv[2];
+ argv[0].v_type = VAR_STRING;
+ argv[1].v_type = VAR_UNKNOWN;
+ argv[0].vval.v_string =
+ (char_u *)(((const char *const[]) {
[kMTBlockWise] = "block",
[kMTLineWise] = "line",
[kMTCharWise] = "char",
- })[oap->motion_type]),
- };
+ })[oap->motion_type]);
// Reset virtual_op so that 'virtualedit' can be changed in the
// function.