mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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
This commit is contained in:
parent
0b4123668a
commit
0364e47ccb
@ -3682,14 +3682,19 @@ expand_by_function (
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Call 'completefunc' to obtain the list of matches.
|
// 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;
|
pos = curwin->w_cursor;
|
||||||
curwin_save = curwin;
|
curwin_save = curwin;
|
||||||
curbuf_save = curbuf;
|
curbuf_save = curbuf;
|
||||||
|
|
||||||
/* Call a function, which returns a list or dict. */
|
// Call a function, which returns a list or dict.
|
||||||
if (call_vim_function(funcname, 2, args, FALSE, FALSE, &rettv) == OK) {
|
if (call_vim_function(funcname, 2, args, false, &rettv) == OK) {
|
||||||
switch (rettv.v_type) {
|
switch (rettv.v_type) {
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
matchlist = rettv.vval.v_list;
|
matchlist = rettv.vval.v_list;
|
||||||
@ -4892,7 +4897,13 @@ static int ins_complete(int c, bool enable_pum)
|
|||||||
return FAIL;
|
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;
|
pos = curwin->w_cursor;
|
||||||
curwin_save = curwin;
|
curwin_save = curwin;
|
||||||
curbuf_save = curbuf;
|
curbuf_save = curbuf;
|
||||||
|
@ -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".
|
// Call some vim script function and return the result in "*rettv".
|
||||||
// Uses argv[argc] for the function arguments. Only Number and String
|
// Uses argv[argc-1] for the function arguments. argv[argc]
|
||||||
// arguments are currently supported.
|
// should have type VAR_UNKNOWN.
|
||||||
//
|
//
|
||||||
// Return OK or FAIL.
|
// Return OK or FAIL.
|
||||||
int call_vim_function(
|
int call_vim_function(
|
||||||
const char_u *func,
|
const char_u *func,
|
||||||
int argc,
|
int argc,
|
||||||
const char_u *const *const argv,
|
typval_T *argv,
|
||||||
bool safe, // use the sandbox
|
int safe, // use the sandbox
|
||||||
int str_arg_only, // all arguments are strings
|
|
||||||
typval_T *rettv
|
typval_T *rettv
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
varnumber_T n;
|
|
||||||
int len;
|
|
||||||
int doesrange;
|
int doesrange;
|
||||||
void *save_funccalp = NULL;
|
void *save_funccalp = NULL;
|
||||||
int ret;
|
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) {
|
if (safe) {
|
||||||
save_funccalp = save_funccal();
|
save_funccalp = save_funccal();
|
||||||
++sandbox;
|
++sandbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
rettv->v_type = VAR_UNKNOWN; // tv_clear() uses this.
|
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,
|
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
|
||||||
&doesrange, true, NULL, NULL);
|
&doesrange, true, NULL, NULL);
|
||||||
if (safe) {
|
if (safe) {
|
||||||
--sandbox;
|
--sandbox;
|
||||||
restore_funccal(save_funccalp);
|
restore_funccal(save_funccalp);
|
||||||
}
|
}
|
||||||
xfree(argvars);
|
|
||||||
|
|
||||||
if (ret == FAIL) {
|
if (ret == FAIL) {
|
||||||
tv_clear(rettv);
|
tv_clear(rettv);
|
||||||
@ -1344,47 +1311,44 @@ int call_vim_function(
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call Vim script function and return the result as a number
|
/// Call Vim script function and return the result as a number
|
||||||
///
|
///
|
||||||
/// @param[in] func Function name.
|
/// @param[in] func Function name.
|
||||||
/// @param[in] argc Number of arguments.
|
/// @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.
|
/// @param[in] safe Use with sandbox.
|
||||||
///
|
///
|
||||||
/// @return -1 when calling function fails, result of function otherwise.
|
/// @return -1 when calling function fails, result of function otherwise.
|
||||||
varnumber_T call_func_retnr(char_u *func, int argc,
|
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;
|
typval_T rettv;
|
||||||
varnumber_T retval;
|
varnumber_T retval;
|
||||||
|
|
||||||
/* All arguments are passed as strings, no conversion to number. */
|
if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) {
|
||||||
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
retval = tv_get_number_chk(&rettv, NULL);
|
retval = tv_get_number_chk(&rettv, NULL);
|
||||||
tv_clear(&rettv);
|
tv_clear(&rettv);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call Vim script function and return the result as a string
|
/// Call Vim script function and return the result as a string
|
||||||
///
|
///
|
||||||
/// @param[in] func Function name.
|
/// @param[in] func Function name.
|
||||||
/// @param[in] argc Number of arguments.
|
/// @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.
|
/// @param[in] safe Use the sandbox.
|
||||||
///
|
///
|
||||||
/// @return [allocated] NULL when calling function fails, allocated string
|
/// @return [allocated] NULL when calling function fails, allocated string
|
||||||
/// otherwise.
|
/// otherwise.
|
||||||
char *call_func_retstr(const char *const func, int argc,
|
char *call_func_retstr(const char *const func, int argc,
|
||||||
const char_u *const *argv,
|
typval_T *argv,
|
||||||
bool safe)
|
bool safe)
|
||||||
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
|
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
|
||||||
{
|
{
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
// All arguments are passed as strings, no conversion to number.
|
// 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) {
|
== FAIL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1393,24 +1357,24 @@ char *call_func_retstr(const char *const func, int argc,
|
|||||||
tv_clear(&rettv);
|
tv_clear(&rettv);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call Vim script function and return the result as a List
|
/// Call Vim script function and return the result as a List
|
||||||
///
|
///
|
||||||
/// @param[in] func Function name.
|
/// @param[in] func Function name.
|
||||||
/// @param[in] argc Number of arguments.
|
/// @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.
|
/// @param[in] safe Use the sandbox.
|
||||||
///
|
///
|
||||||
/// @return [allocated] NULL when calling function fails or return tv is not a
|
/// @return [allocated] NULL when calling function fails or return tv is not a
|
||||||
/// List, allocated List otherwise.
|
/// 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)
|
bool safe)
|
||||||
{
|
{
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
|
|
||||||
/* All arguments are passed as strings, no conversion to number. */
|
// 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 NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (rettv.v_type != VAR_LIST) {
|
if (rettv.v_type != VAR_LIST) {
|
||||||
tv_clear(&rettv);
|
tv_clear(&rettv);
|
||||||
@ -23892,6 +23856,8 @@ bool eval_has_provider(const char *name)
|
|||||||
static int has_python = -1;
|
static int has_python = -1;
|
||||||
static int has_python3 = -1;
|
static int has_python3 = -1;
|
||||||
static int has_ruby = -1;
|
static int has_ruby = -1;
|
||||||
|
typval_T args[1];
|
||||||
|
args[0].v_type = VAR_UNKNOWN;
|
||||||
|
|
||||||
if (strequal(name, "clipboard")) {
|
if (strequal(name, "clipboard")) {
|
||||||
CHECK_PROVIDER(clipboard);
|
CHECK_PROVIDER(clipboard);
|
||||||
@ -23906,7 +23872,7 @@ bool eval_has_provider(const char *name)
|
|||||||
bool need_check_ruby = (has_ruby == -1);
|
bool need_check_ruby = (has_ruby == -1);
|
||||||
CHECK_PROVIDER(ruby);
|
CHECK_PROVIDER(ruby);
|
||||||
if (need_check_ruby && has_ruby == 1) {
|
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) {
|
||||||
if (*rubyhost == NUL) {
|
if (*rubyhost == NUL) {
|
||||||
// Invalid rubyhost executable. Gem is probably not installed.
|
// Invalid rubyhost executable. Gem is probably not installed.
|
||||||
|
@ -200,7 +200,7 @@ static Array cmdline_block = ARRAY_DICT_INIT;
|
|||||||
*/
|
*/
|
||||||
typedef void *(*user_expand_func_T)(const char_u *,
|
typedef void *(*user_expand_func_T)(const char_u *,
|
||||||
int,
|
int,
|
||||||
const char_u * const *,
|
typval_T *,
|
||||||
bool);
|
bool);
|
||||||
|
|
||||||
static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
|
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)
|
expand_T *xp, int *num_file, char_u ***file)
|
||||||
{
|
{
|
||||||
char_u keep = 0;
|
char_u keep = 0;
|
||||||
char_u num[50];
|
typval_T args[4];
|
||||||
char_u *args[3];
|
char_u *pat = NULL;
|
||||||
int save_current_SID = current_SID;
|
int save_current_SID = current_SID;
|
||||||
void *ret;
|
void *ret;
|
||||||
struct cmdline_info save_ccline;
|
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;
|
ccline.cmdbuff[ccline.cmdlen] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
args[0] = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
|
pat = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
|
||||||
args[1] = xp->xp_line;
|
args[0].v_type = VAR_STRING;
|
||||||
sprintf((char *)num, "%d", xp->xp_col);
|
args[1].v_type = VAR_STRING;
|
||||||
args[2] = num;
|
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 the cmdline, we don't know what the function may do. */
|
||||||
save_ccline = ccline;
|
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,
|
ret = user_expand_func(xp->xp_arg,
|
||||||
3,
|
3,
|
||||||
(const char_u * const *)args,
|
args,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
ccline = save_ccline;
|
ccline = save_ccline;
|
||||||
@ -5088,7 +5092,7 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
|
|||||||
if (ccline.cmdbuff != NULL)
|
if (ccline.cmdbuff != NULL)
|
||||||
ccline.cmdbuff[ccline.cmdlen] = keep;
|
ccline.cmdbuff[ccline.cmdlen] = keep;
|
||||||
|
|
||||||
xfree(args[0]);
|
xfree(pat);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2096,13 +2096,15 @@ static void op_function(oparg_T *oap)
|
|||||||
decl(&curbuf->b_op_end);
|
decl(&curbuf->b_op_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char_u *const argv[1] = {
|
typval_T argv[2];
|
||||||
(const char_u *)(((const char *const[]) {
|
argv[0].v_type = VAR_STRING;
|
||||||
|
argv[1].v_type = VAR_UNKNOWN;
|
||||||
|
argv[0].vval.v_string =
|
||||||
|
(char_u *)(((const char *const[]) {
|
||||||
[kMTBlockWise] = "block",
|
[kMTBlockWise] = "block",
|
||||||
[kMTLineWise] = "line",
|
[kMTLineWise] = "line",
|
||||||
[kMTCharWise] = "char",
|
[kMTCharWise] = "char",
|
||||||
})[oap->motion_type]),
|
})[oap->motion_type]);
|
||||||
};
|
|
||||||
|
|
||||||
// Reset virtual_op so that 'virtualedit' can be changed in the
|
// Reset virtual_op so that 'virtualedit' can be changed in the
|
||||||
// function.
|
// function.
|
||||||
|
Loading…
Reference in New Issue
Block a user