aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval/funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval/funcs.c')
-rw-r--r--src/nvim/eval/funcs.c57
1 files changed, 52 insertions, 5 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 4e409cca50..8a1258efd4 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -175,6 +175,53 @@ const VimLFuncDef *find_internal_func(const char *const name)
return find_internal_func_gperf(name, len);
}
+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);
+ if (fdef == NULL) {
+ return ERROR_UNKNOWN;
+ } else if (argcount < fdef->min_argc) {
+ return ERROR_TOOFEW;
+ } else if (argcount > fdef->max_argc) {
+ return ERROR_TOOMANY;
+ }
+ argvars[argcount].v_type = VAR_UNKNOWN;
+ fdef->func(argvars, rettv, fdef->data);
+ return ERROR_NONE;
+}
+
+/// Invoke a method for base->method().
+int call_internal_method(const char_u *const fname, const int argcount,
+ typval_T *const argvars, typval_T *const rettv,
+ typval_T *const basetv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ if (fdef == NULL) {
+ return ERROR_UNKNOWN;
+ } else if (fdef->base_arg == BASE_NONE) {
+ return ERROR_NOTMETHOD;
+ } else if (argcount + 1 < fdef->min_argc) {
+ return ERROR_TOOFEW;
+ } else if (argcount + 1 > fdef->max_argc) {
+ return ERROR_TOOMANY;
+ }
+
+ typval_T argv[MAX_FUNC_ARGS + 1];
+ const ptrdiff_t base_index
+ = fdef->base_arg == BASE_LAST ? argcount : fdef->base_arg - 1;
+ memcpy(argv, argvars, base_index * sizeof(typval_T));
+ argv[base_index] = *basetv;
+ memcpy(argv + base_index + 1, argvars + base_index,
+ (argcount - base_index) * sizeof(typval_T));
+ argv[argcount + 1].v_type = VAR_UNKNOWN;
+
+ fdef->func(argv, rettv, fdef->data);
+ return ERROR_NONE;
+}
+
/*
* Return TRUE for a non-zero Number and a non-empty String.
*/
@@ -9420,7 +9467,6 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
int res;
typval_T rettv;
typval_T argv[3];
- int dummy;
const char *func_name;
partial_T *partial = sortinfo->item_compare_partial;
@@ -9444,10 +9490,11 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
tv_copy(TV_LIST_ITEM_TV(si2->item), &argv[1]);
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this
- res = call_func((const char_u *)func_name,
- -1,
- &rettv, 2, argv, NULL, 0L, 0L, &dummy, true,
- partial, sortinfo->item_compare_selfdict);
+ funcexe_T funcexe = FUNCEXE_INIT;
+ 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);
tv_clear(&argv[0]);
tv_clear(&argv[1]);