# HG changeset patch
# User ZyX <[email protected]>
# Date 1369550131 -14400
# Node ID 542435007988a8d87b3739506422ebc7d58f3910
# Parent  0b272b1d066da1229ca6dd2519a3456b4a073f31
Change f_function to use new get_expanded_name function

Reason: fixes the following bugs:

    " function() call succeeds, but call of funcref does not
    echo function("tr ")('a', 'b', 'c')

    " In script number 1
    let g:F = function('s:Eval')
    " In another script
    echo g:F('1')
    " ^ is an error as s: meaning changed. Now it uses expanded names thus
    "   current script context does not matter

    " The following used to create a funcref. Now it does not
    function('#{}]+{}{{}]+}{}')
    " (note the autoload char (#), it is what was causing such behavior)

diff -r 0b272b1d066d -r 542435007988 src/eval.c
--- a/src/eval.c        Sun May 26 02:36:55 2013 +0400
+++ b/src/eval.c        Sun May 26 10:35:31 2013 +0400
@@ -810,7 +810,6 @@
 # endif
        prof_self_cmp __ARGS((const void *s1, const void *s2));
 #endif
-static int script_autoload __ARGS((char_u *name, int reload));
 static char_u *autoload_name __ARGS((char_u *name));
 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
 static void func_free __ARGS((ufunc_T *fp));
@@ -10946,16 +10945,25 @@
     typval_T   *rettv;
 {
     char_u     *s;
+    char_u     *name = NULL;
 
     s = get_tv_string(&argvars[0]);
     if (s == NULL || *s == NUL || VIM_ISDIGIT(*s))
        EMSG2(_(e_invarg2), s);
-    /* Don't check an autoload name for existence here. */
-    else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s))
+    /* Don't check an autoload name for existence here, but still expand it 
+     * checking for validity */
+    else if ((name = get_expanded_name(s, vim_strchr(s, AUTOLOAD_CHAR) == 
NULL))
+                                                                       == NULL)
        EMSG2(_("E700: Unknown function: %s"), s);
     else
     {
-       rettv->vval.v_string = vim_strsave(s);
+       if (name == NULL)
+           /* Autoload function, need to copy string */
+           rettv->vval.v_string = vim_strsave(s);
+       else
+           /* Function found by get_expanded_name, string allocated by 
+            * trans_function_name: no need to copy */
+           rettv->vval.v_string = name;
        rettv->v_type = VAR_FUNC;
     }
 }
@@ -21938,6 +21946,33 @@
     return n;
 }
 
+    char_u *
+get_expanded_name(name, check)
+    char_u     *name;
+    int                check;
+{
+    char_u     *nm = name;
+    char_u     *p;
+
+    p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
+
+    if (p != NULL && *nm == NUL)
+    {
+       if (!check)
+           return p;
+       else if (builtin_function(p))
+       {
+           if (find_internal_func(p) >= 0)
+               return p;
+       }
+       else
+           if (find_func(p) != NULL)
+               return p;
+    }
+    vim_free(p);
+    return NULL;
+}
+
 /*
  * Return TRUE if "name" looks like a builtin function name: starts with a
  * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR.
@@ -22146,7 +22181,7 @@
  * If "name" has a package name try autoloading the script for it.
  * Return TRUE if a package was loaded.
  */
-    static int
+    int
 script_autoload(name, reload)
     char_u     *name;
     int                reload;     /* load script again when already loaded */
diff -r 0b272b1d066d -r 542435007988 src/proto/eval.pro
--- a/src/proto/eval.pro        Sun May 26 02:36:55 2013 +0400
+++ b/src/proto/eval.pro        Sun May 26 10:35:31 2013 +0400
@@ -77,6 +77,7 @@
 long get_dict_number __ARGS((dict_T *d, char_u *key));
 char_u *get_function_name __ARGS((expand_T *xp, int idx));
 char_u *get_expr_name __ARGS((expand_T *xp, int idx));
+char_u *get_expanded_name __ARGS((char_u *name, int check));
 int func_call __ARGS((char_u *name, typval_T *args, dict_T *selfdict, typval_T 
*rettv));
 void mzscheme_call_vim __ARGS((char_u *name, typval_T *args, typval_T *rettv));
 long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, 
char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long 
time_limit));
@@ -129,4 +130,5 @@
 void ex_oldfiles __ARGS((exarg_T *eap));
 int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u 
**bufp, int *fnamelen));
 char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub, char_u 
*flags));
+int script_autoload __ARGS((char_u *name, int reload));
 /* vim: set ft=c : */

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


diff -cr vim.0b272b1d066d/src/eval.c vim.542435007988/src/eval.c
*** vim.0b272b1d066d/src/eval.c	2013-05-26 12:10:02.840386115 +0400
--- vim.542435007988/src/eval.c	2013-05-26 12:10:02.858385947 +0400
***************
*** 810,816 ****
  # endif
  	prof_self_cmp __ARGS((const void *s1, const void *s2));
  #endif
- static int script_autoload __ARGS((char_u *name, int reload));
  static char_u *autoload_name __ARGS((char_u *name));
  static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
  static void func_free __ARGS((ufunc_T *fp));
--- 810,815 ----
***************
*** 10946,10961 ****
      typval_T	*rettv;
  {
      char_u	*s;
  
      s = get_tv_string(&argvars[0]);
      if (s == NULL || *s == NUL || VIM_ISDIGIT(*s))
  	EMSG2(_(e_invarg2), s);
!     /* Don't check an autoload name for existence here. */
!     else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s))
  	EMSG2(_("E700: Unknown function: %s"), s);
      else
      {
! 	rettv->vval.v_string = vim_strsave(s);
  	rettv->v_type = VAR_FUNC;
      }
  }
--- 10945,10969 ----
      typval_T	*rettv;
  {
      char_u	*s;
+     char_u	*name = NULL;
  
      s = get_tv_string(&argvars[0]);
      if (s == NULL || *s == NUL || VIM_ISDIGIT(*s))
  	EMSG2(_(e_invarg2), s);
!     /* Don't check an autoload name for existence here, but still expand it 
!      * checking for validity */
!     else if ((name = get_expanded_name(s, vim_strchr(s, AUTOLOAD_CHAR) == NULL))
! 									== NULL)
  	EMSG2(_("E700: Unknown function: %s"), s);
      else
      {
! 	if (name == NULL)
! 	    /* Autoload function, need to copy string */
! 	    rettv->vval.v_string = vim_strsave(s);
! 	else
! 	    /* Function found by get_expanded_name, string allocated by 
! 	     * trans_function_name: no need to copy */
! 	    rettv->vval.v_string = name;
  	rettv->v_type = VAR_FUNC;
      }
  }
***************
*** 21938,21943 ****
--- 21946,21978 ----
      return n;
  }
  
+     char_u *
+ get_expanded_name(name, check)
+     char_u	*name;
+     int		check;
+ {
+     char_u	*nm = name;
+     char_u	*p;
+ 
+     p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
+ 
+     if (p != NULL && *nm == NUL)
+     {
+ 	if (!check)
+ 	    return p;
+ 	else if (builtin_function(p))
+ 	{
+ 	    if (find_internal_func(p) >= 0)
+ 		return p;
+ 	}
+ 	else
+ 	    if (find_func(p) != NULL)
+ 		return p;
+     }
+     vim_free(p);
+     return NULL;
+ }
+ 
  /*
   * Return TRUE if "name" looks like a builtin function name: starts with a
   * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR.
***************
*** 22146,22152 ****
   * If "name" has a package name try autoloading the script for it.
   * Return TRUE if a package was loaded.
   */
!     static int
  script_autoload(name, reload)
      char_u	*name;
      int		reload;	    /* load script again when already loaded */
--- 22181,22187 ----
   * If "name" has a package name try autoloading the script for it.
   * Return TRUE if a package was loaded.
   */
!     int
  script_autoload(name, reload)
      char_u	*name;
      int		reload;	    /* load script again when already loaded */
diff -cr vim.0b272b1d066d/src/proto/eval.pro vim.542435007988/src/proto/eval.pro
*** vim.0b272b1d066d/src/proto/eval.pro	2013-05-26 12:10:02.825386256 +0400
--- vim.542435007988/src/proto/eval.pro	2013-05-26 12:10:02.844386079 +0400
***************
*** 77,82 ****
--- 77,83 ----
  long get_dict_number __ARGS((dict_T *d, char_u *key));
  char_u *get_function_name __ARGS((expand_T *xp, int idx));
  char_u *get_expr_name __ARGS((expand_T *xp, int idx));
+ char_u *get_expanded_name __ARGS((char_u *name, int check));
  int func_call __ARGS((char_u *name, typval_T *args, dict_T *selfdict, typval_T *rettv));
  void mzscheme_call_vim __ARGS((char_u *name, typval_T *args, typval_T *rettv));
  long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit));
***************
*** 129,132 ****
--- 130,134 ----
  void ex_oldfiles __ARGS((exarg_T *eap));
  int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen));
  char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub, char_u *flags));
+ int script_autoload __ARGS((char_u *name, int reload));
  /* vim: set ft=c : */

Raspunde prin e-mail lui