@@ -110,7 +110,6 @@ static char *e_illvar = N_("E461: Illegal variable name: %s");
110110#ifdef FEAT_FLOAT
111111static char *e_float_as_string = N_("E806: using Float as a String");
112112#endif
113- static char *e_dict_both = N_("E924: can't have both a \"self\" dict and a partial: %s");
114113
115114#define NAMESPACE_CHAR (char_u *)"abglstvw"
116115
@@ -8678,61 +8677,28 @@ get_func_tv(
86788677 return ret;
86798678}
86808679
8681-
8682- /*
8683- * Call a function with its resolved parameters
8684- * Return FAIL when the function can't be called, OK otherwise.
8685- * Also returns OK when an error was encountered while executing the function.
8686- */
8687- int
8688- call_func(
8689- char_u *funcname, /* name of the function */
8690- int len, /* length of "name" */
8691- typval_T *rettv, /* return value goes here */
8692- int argcount_in, /* number of "argvars" */
8693- typval_T *argvars_in, /* vars for arguments, must have "argcount"
8694- PLUS ONE elements! */
8695- linenr_T firstline, /* first line of range */
8696- linenr_T lastline, /* last line of range */
8697- int *doesrange, /* return: function handled range */
8698- int evaluate,
8699- partial_T *partial, /* optional, can be NULL */
8700- dict_T *selfdict_in) /* Dictionary for "self" */
8701- {
8702- int ret = FAIL;
87038680#define ERROR_UNKNOWN 0
87048681#define ERROR_TOOMANY 1
87058682#define ERROR_TOOFEW 2
87068683#define ERROR_SCRIPT 3
87078684#define ERROR_DICT 4
87088685#define ERROR_NONE 5
87098686#define ERROR_OTHER 6
8710- #define ERROR_BOTH 7
8711- int error = ERROR_NONE;
8712- int i;
8713- int llen;
8714- ufunc_T *fp;
87158687#define FLEN_FIXED 40
8716- char_u fname_buf[FLEN_FIXED + 1];
8717- char_u *fname;
8718- char_u *name;
8719- int argcount = argcount_in;
8720- typval_T *argvars = argvars_in;
8721- dict_T *selfdict = selfdict_in;
8722- typval_T argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */
8723- int argv_clear = 0;
87248688
8725- /* Make a copy of the name, if it comes from a funcref variable it could
8726- * be changed or deleted in the called function. */
8727- name = vim_strnsave(funcname, len);
8728- if (name == NULL)
8729- return ret;
8689+ /*
8690+ * In a script change <SID>name() and s:name() to K_SNR 123_name().
8691+ * Change <SNR>123_name() to K_SNR 123_name().
8692+ * Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory
8693+ * (slow).
8694+ */
8695+ static char_u *
8696+ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
8697+ {
8698+ int llen;
8699+ char_u *fname;
8700+ int i;
87308701
8731- /*
8732- * In a script change <SID>name() and s:name() to K_SNR 123_name().
8733- * Change <SNR>123_name() to K_SNR 123_name().
8734- * Use fname_buf[] when it fits, otherwise allocate memory (slow).
8735- */
87368702 llen = eval_fname_script(name);
87378703 if (llen > 0)
87388704 {
@@ -8743,7 +8709,7 @@ call_func(
87438709 if (eval_fname_sid(name)) /* "<SID>" or "s:" */
87448710 {
87458711 if (current_SID <= 0)
8746- error = ERROR_SCRIPT;
8712+ * error = ERROR_SCRIPT;
87478713 else
87488714 {
87498715 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID);
@@ -8759,26 +8725,73 @@ call_func(
87598725 {
87608726 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1));
87618727 if (fname == NULL)
8762- error = ERROR_OTHER;
8728+ * error = ERROR_OTHER;
87638729 else
87648730 {
8731+ *tofree = fname;
87658732 mch_memmove(fname, fname_buf, (size_t)i);
87668733 STRCPY(fname + i, name + llen);
87678734 }
87688735 }
87698736 }
87708737 else
87718738 fname = name;
8739+ return fname;
8740+ }
8741+
8742+ /*
8743+ * Call a function with its resolved parameters
8744+ * Return FAIL when the function can't be called, OK otherwise.
8745+ * Also returns OK when an error was encountered while executing the function.
8746+ */
8747+ int
8748+ call_func(
8749+ char_u *funcname, /* name of the function */
8750+ int len, /* length of "name" */
8751+ typval_T *rettv, /* return value goes here */
8752+ int argcount_in, /* number of "argvars" */
8753+ typval_T *argvars_in, /* vars for arguments, must have "argcount"
8754+ PLUS ONE elements! */
8755+ linenr_T firstline, /* first line of range */
8756+ linenr_T lastline, /* last line of range */
8757+ int *doesrange, /* return: function handled range */
8758+ int evaluate,
8759+ partial_T *partial, /* optional, can be NULL */
8760+ dict_T *selfdict_in) /* Dictionary for "self" */
8761+ {
8762+ int ret = FAIL;
8763+ int error = ERROR_NONE;
8764+ int i;
8765+ ufunc_T *fp;
8766+ char_u fname_buf[FLEN_FIXED + 1];
8767+ char_u *tofree = NULL;
8768+ char_u *fname;
8769+ char_u *name;
8770+ int argcount = argcount_in;
8771+ typval_T *argvars = argvars_in;
8772+ dict_T *selfdict = selfdict_in;
8773+ typval_T argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */
8774+ int argv_clear = 0;
8775+
8776+ /* Make a copy of the name, if it comes from a funcref variable it could
8777+ * be changed or deleted in the called function. */
8778+ name = vim_strnsave(funcname, len);
8779+ if (name == NULL)
8780+ return ret;
8781+
8782+ fname = fname_trans_sid(name, fname_buf, &tofree, &error);
87728783
87738784 *doesrange = FALSE;
87748785
87758786 if (partial != NULL)
87768787 {
87778788 if (partial->pt_dict != NULL)
87788789 {
8779- if (selfdict_in != NULL)
8780- error = ERROR_BOTH;
8781- selfdict = partial->pt_dict;
8790+ /* When the function has a partial with a dict and there is a dict
8791+ * argument, use the dict argument. That is backwards compatible.
8792+ */
8793+ if (selfdict_in == NULL)
8794+ selfdict = partial->pt_dict;
87828795 }
87838796 if (error == ERROR_NONE && partial->pt_argc > 0)
87848797 {
@@ -8934,16 +8947,12 @@ call_func(
89348947 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
89358948 name);
89368949 break;
8937- case ERROR_BOTH:
8938- emsg_funcname(e_dict_both, name);
8939- break;
89408950 }
89418951 }
89428952
89438953 while (argv_clear > 0)
89448954 clear_tv(&argv[--argv_clear]);
8945- if (fname != name && fname != fname_buf)
8946- vim_free(fname);
8955+ vim_free(tofree);
89478956 vim_free(name);
89488957
89498958 return ret;
@@ -11876,12 +11885,6 @@ f_function(typval_T *argvars, typval_T *rettv)
1187611885 vim_free(name);
1187711886 return;
1187811887 }
11879- if (argvars[0].v_type == VAR_PARTIAL)
11880- {
11881- EMSG2(_(e_dict_both), name);
11882- vim_free(name);
11883- return;
11884- }
1188511888 if (argvars[dict_idx].vval.v_dict == NULL)
1188611889 dict_idx = 0;
1188711890 }
@@ -11925,14 +11928,16 @@ f_function(typval_T *argvars, typval_T *rettv)
1192511928 }
1192611929 }
1192711930
11928- if (argvars[0].v_type == VAR_PARTIAL)
11931+ /* For "function(dict.func, [], dict)" and "func" is a partial
11932+ * use "dict". That is backwards compatible. */
11933+ if (dict_idx > 0)
1192911934 {
11930- pt->pt_dict = argvars[0 ].vval.v_partial->pt_dict ;
11935+ pt->pt_dict = argvars[dict_idx ].vval.v_dict ;
1193111936 ++pt->pt_dict->dv_refcount;
1193211937 }
11933- else if (dict_idx > 0 )
11938+ else if (argvars[0].v_type == VAR_PARTIAL )
1193411939 {
11935- pt->pt_dict = argvars[dict_idx ].vval.v_dict ;
11940+ pt->pt_dict = argvars[0 ].vval.v_partial->pt_dict ;
1193611941 ++pt->pt_dict->dv_refcount;
1193711942 }
1193811943
@@ -21714,7 +21719,17 @@ handle_subscript(
2171421719
2171521720 if (rettv->v_type == VAR_FUNC && selfdict != NULL)
2171621721 {
21717- ufunc_T *fp = find_func(rettv->vval.v_string);
21722+ char_u *fname;
21723+ char_u *tofree = NULL;
21724+ ufunc_T *fp;
21725+ char_u fname_buf[FLEN_FIXED + 1];
21726+ int error;
21727+
21728+ /* Translate "s:func" to the stored function name. */
21729+ fname = fname_trans_sid(rettv->vval.v_string, fname_buf,
21730+ &tofree, &error);
21731+ fp = find_func(fname);
21732+ vim_free(tofree);
2171821733
2171921734 /* Turn "dict.Func" into a partial for "Func" with "dict". */
2172021735 if (fp != NULL && (fp->uf_flags & FC_DICT))
0 commit comments