diff options
author | cangscop <cangscop@gmail.com> | 2019-07-27 03:13:29 +0200 |
---|---|---|
committer | cangscop <cangscop@gmail.com> | 2019-07-27 16:25:33 +0200 |
commit | 0364e47ccb8705d48146f00d68506d5f9cefb0aa (patch) | |
tree | a3d527e3440f29b6babcc7a80cd43c77445f73cb /src | |
parent | 0b4123668af65b489e188dfb1041e664a4ee3915 (diff) | |
download | rneovim-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.c | 19 | ||||
-rw-r--r-- | src/nvim/eval.c | 74 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 22 | ||||
-rw-r--r-- | src/nvim/normal.c | 10 |
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. |