Karsten Hopp 0cf1c3
To: vim_dev@googlegroups.com
Karsten Hopp 0cf1c3
Subject: Patch 7.4.260
Karsten Hopp 0cf1c3
Fcc: outbox
Karsten Hopp 0cf1c3
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 0cf1c3
Mime-Version: 1.0
Karsten Hopp 0cf1c3
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 0cf1c3
Content-Transfer-Encoding: 8bit
Karsten Hopp 0cf1c3
------------
Karsten Hopp 0cf1c3
Karsten Hopp 0cf1c3
Patch 7.4.260
Karsten Hopp 0cf1c3
Problem:    It is possible to define a function with a colon in the name.  It
Karsten Hopp 0cf1c3
	    is possible to define a function with a lower case character if a
Karsten Hopp 0cf1c3
	    "#" appears after the name.
Karsten Hopp 0cf1c3
Solution:   Disallow using a colon other than with "s:".  Ignore "#" after the
Karsten Hopp 0cf1c3
	    name.
Karsten Hopp 0cf1c3
Files:	    runtime/doc/eval.txt, src/eval.c, src/testdir/test_eval.in,
Karsten Hopp 0cf1c3
	    src/testdir/test_eval.ok
Karsten Hopp 0cf1c3
Karsten Hopp 0cf1c3
Karsten Hopp 0cf1c3
*** ../vim-7.4.259/runtime/doc/eval.txt	2014-04-05 19:44:36.891160723 +0200
Karsten Hopp 0cf1c3
--- runtime/doc/eval.txt	2014-04-23 17:19:57.914982886 +0200
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 123,128 ****
Karsten Hopp 0cf1c3
--- 123,129 ----
Karsten Hopp 0cf1c3
  	:echo Fn()
Karsten Hopp 0cf1c3
  <							*E704* *E705* *E707*
Karsten Hopp 0cf1c3
  A Funcref variable must start with a capital, "s:", "w:", "t:" or "b:".  You
Karsten Hopp 0cf1c3
+ can use "g:" but the following name must still start with a capital.  You
Karsten Hopp 0cf1c3
  cannot have both a Funcref variable and a function with the same name.
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  A special case is defining a function and directly assigning its Funcref to a
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 6675,6680 ****
Karsten Hopp 0cf1c3
--- 6691,6698 ----
Karsten Hopp 0cf1c3
  and autocommands defined in the script.  It is also possible to call the
Karsten Hopp 0cf1c3
  function from a mapping defined in the script, but then |<SID>| must be used
Karsten Hopp 0cf1c3
  instead of "s:" when the mapping is expanded outside of the script.
Karsten Hopp 0cf1c3
+ There are only script-local functions, no buffer-local or window-local
Karsten Hopp 0cf1c3
+ functions.
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  					*:fu* *:function* *E128* *E129* *E123*
Karsten Hopp 0cf1c3
  :fu[nction]		List all functions and their arguments.
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 6698,6708 ****
Karsten Hopp 0cf1c3
  <
Karsten Hopp 0cf1c3
  See |:verbose-cmd| for more information.
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
! 							*E124* *E125* *E853*
Karsten Hopp 0cf1c3
  :fu[nction][!] {name}([arguments]) [range] [abort] [dict]
Karsten Hopp 0cf1c3
  			Define a new function by the name {name}.  The name
Karsten Hopp 0cf1c3
  			must be made of alphanumeric characters and '_', and
Karsten Hopp 0cf1c3
! 			must start with a capital or "s:" (see above).
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  			{name} can also be a |Dictionary| entry that is a
Karsten Hopp 0cf1c3
  			|Funcref|: >
Karsten Hopp 0cf1c3
--- 6716,6727 ----
Karsten Hopp 0cf1c3
  <
Karsten Hopp 0cf1c3
  See |:verbose-cmd| for more information.
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
! 						*E124* *E125* *E853* *E884*
Karsten Hopp 0cf1c3
  :fu[nction][!] {name}([arguments]) [range] [abort] [dict]
Karsten Hopp 0cf1c3
  			Define a new function by the name {name}.  The name
Karsten Hopp 0cf1c3
  			must be made of alphanumeric characters and '_', and
Karsten Hopp 0cf1c3
! 			must start with a capital or "s:" (see above).  Note
Karsten Hopp 0cf1c3
! 			that using "b:" or "g:" is not allowed.
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  			{name} can also be a |Dictionary| entry that is a
Karsten Hopp 0cf1c3
  			|Funcref|: >
Karsten Hopp 0cf1c3
*** ../vim-7.4.259/src/eval.c	2014-04-11 10:22:46.288219453 +0200
Karsten Hopp 0cf1c3
--- src/eval.c	2014-04-23 17:37:23.890957682 +0200
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 808,814 ****
Karsten Hopp 0cf1c3
  static void list_func_head __ARGS((ufunc_T *fp, int indent));
Karsten Hopp 0cf1c3
  static ufunc_T *find_func __ARGS((char_u *name));
Karsten Hopp 0cf1c3
  static int function_exists __ARGS((char_u *name));
Karsten Hopp 0cf1c3
! static int builtin_function __ARGS((char_u *name));
Karsten Hopp 0cf1c3
  #ifdef FEAT_PROFILE
Karsten Hopp 0cf1c3
  static void func_do_profile __ARGS((ufunc_T *fp));
Karsten Hopp 0cf1c3
  static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self));
Karsten Hopp 0cf1c3
--- 808,814 ----
Karsten Hopp 0cf1c3
  static void list_func_head __ARGS((ufunc_T *fp, int indent));
Karsten Hopp 0cf1c3
  static ufunc_T *find_func __ARGS((char_u *name));
Karsten Hopp 0cf1c3
  static int function_exists __ARGS((char_u *name));
Karsten Hopp 0cf1c3
! static int builtin_function __ARGS((char_u *name, int len));
Karsten Hopp 0cf1c3
  #ifdef FEAT_PROFILE
Karsten Hopp 0cf1c3
  static void func_do_profile __ARGS((ufunc_T *fp));
Karsten Hopp 0cf1c3
  static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self));
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 8489,8495 ****
Karsten Hopp 0cf1c3
  	rettv->vval.v_number = 0;
Karsten Hopp 0cf1c3
  	error = ERROR_UNKNOWN;
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
! 	if (!builtin_function(fname))
Karsten Hopp 0cf1c3
  	{
Karsten Hopp 0cf1c3
  	    /*
Karsten Hopp 0cf1c3
  	     * User defined function.
Karsten Hopp 0cf1c3
--- 8489,8495 ----
Karsten Hopp 0cf1c3
  	rettv->vval.v_number = 0;
Karsten Hopp 0cf1c3
  	error = ERROR_UNKNOWN;
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
! 	if (!builtin_function(fname, -1))
Karsten Hopp 0cf1c3
  	{
Karsten Hopp 0cf1c3
  	    /*
Karsten Hopp 0cf1c3
  	     * User defined function.
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 21584,21589 ****
Karsten Hopp 0cf1c3
--- 21584,21590 ----
Karsten Hopp 0cf1c3
       * Get the function name.  There are these situations:
Karsten Hopp 0cf1c3
       * func	    normal function name
Karsten Hopp 0cf1c3
       *		    "name" == func, "fudi.fd_dict" == NULL
Karsten Hopp 0cf1c3
+      * s:func	    script-local function name
Karsten Hopp 0cf1c3
       * dict.func    new dictionary entry
Karsten Hopp 0cf1c3
       *		    "name" == NULL, "fudi.fd_dict" set,
Karsten Hopp 0cf1c3
       *		    "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 22314,22324 ****
Karsten Hopp 0cf1c3
  	    lead += (int)STRLEN(sid_buf);
Karsten Hopp 0cf1c3
  	}
Karsten Hopp 0cf1c3
      }
Karsten Hopp 0cf1c3
!     else if (!(flags & TFN_INT) && builtin_function(lv.ll_name))
Karsten Hopp 0cf1c3
      {
Karsten Hopp 0cf1c3
! 	EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name);
Karsten Hopp 0cf1c3
  	goto theend;
Karsten Hopp 0cf1c3
      }
Karsten Hopp 0cf1c3
      name = alloc((unsigned)(len + lead + 1));
Karsten Hopp 0cf1c3
      if (name != NULL)
Karsten Hopp 0cf1c3
      {
Karsten Hopp 0cf1c3
--- 22315,22338 ----
Karsten Hopp 0cf1c3
  	    lead += (int)STRLEN(sid_buf);
Karsten Hopp 0cf1c3
  	}
Karsten Hopp 0cf1c3
      }
Karsten Hopp 0cf1c3
!     else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len))
Karsten Hopp 0cf1c3
      {
Karsten Hopp 0cf1c3
! 	EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"),
Karsten Hopp 0cf1c3
! 								  lv.ll_name);
Karsten Hopp 0cf1c3
  	goto theend;
Karsten Hopp 0cf1c3
      }
Karsten Hopp 0cf1c3
+     if (!skip)
Karsten Hopp 0cf1c3
+     {
Karsten Hopp 0cf1c3
+ 	char_u *cp = vim_strchr(lv.ll_name, ':');
Karsten Hopp 0cf1c3
+ 
Karsten Hopp 0cf1c3
+ 	if (cp != NULL && cp < end)
Karsten Hopp 0cf1c3
+ 	{
Karsten Hopp 0cf1c3
+ 	    EMSG2(_("E884: Function name cannot contain a colon: %s"),
Karsten Hopp 0cf1c3
+ 								  lv.ll_name);
Karsten Hopp 0cf1c3
+ 	    goto theend;
Karsten Hopp 0cf1c3
+ 	}
Karsten Hopp 0cf1c3
+     }
Karsten Hopp 0cf1c3
+ 
Karsten Hopp 0cf1c3
      name = alloc((unsigned)(len + lead + 1));
Karsten Hopp 0cf1c3
      if (name != NULL)
Karsten Hopp 0cf1c3
      {
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 22331,22337 ****
Karsten Hopp 0cf1c3
  		STRCPY(name + 3, sid_buf);
Karsten Hopp 0cf1c3
  	}
Karsten Hopp 0cf1c3
  	mch_memmove(name + lead, lv.ll_name, (size_t)len);
Karsten Hopp 0cf1c3
! 	name[len + lead] = NUL;
Karsten Hopp 0cf1c3
      }
Karsten Hopp 0cf1c3
      *pp = end;
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
--- 22345,22351 ----
Karsten Hopp 0cf1c3
  		STRCPY(name + 3, sid_buf);
Karsten Hopp 0cf1c3
  	}
Karsten Hopp 0cf1c3
  	mch_memmove(name + lead, lv.ll_name, (size_t)len);
Karsten Hopp 0cf1c3
! 	name[lead + len] = NUL;
Karsten Hopp 0cf1c3
      }
Karsten Hopp 0cf1c3
      *pp = end;
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 22452,22458 ****
Karsten Hopp 0cf1c3
  translated_function_exists(name)
Karsten Hopp 0cf1c3
      char_u	*name;
Karsten Hopp 0cf1c3
  {
Karsten Hopp 0cf1c3
!     if (builtin_function(name))
Karsten Hopp 0cf1c3
  	return find_internal_func(name) >= 0;
Karsten Hopp 0cf1c3
      return find_func(name) != NULL;
Karsten Hopp 0cf1c3
  }
Karsten Hopp 0cf1c3
--- 22466,22472 ----
Karsten Hopp 0cf1c3
  translated_function_exists(name)
Karsten Hopp 0cf1c3
      char_u	*name;
Karsten Hopp 0cf1c3
  {
Karsten Hopp 0cf1c3
!     if (builtin_function(name, -1))
Karsten Hopp 0cf1c3
  	return find_internal_func(name) >= 0;
Karsten Hopp 0cf1c3
      return find_func(name) != NULL;
Karsten Hopp 0cf1c3
  }
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 22500,22513 ****
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  /*
Karsten Hopp 0cf1c3
   * Return TRUE if "name" looks like a builtin function name: starts with a
Karsten Hopp 0cf1c3
!  * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR.
Karsten Hopp 0cf1c3
   */
Karsten Hopp 0cf1c3
      static int
Karsten Hopp 0cf1c3
! builtin_function(name)
Karsten Hopp 0cf1c3
      char_u *name;
Karsten Hopp 0cf1c3
  {
Karsten Hopp 0cf1c3
!     return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL
Karsten Hopp 0cf1c3
! 				   && vim_strchr(name, AUTOLOAD_CHAR) == NULL;
Karsten Hopp 0cf1c3
  }
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  #if defined(FEAT_PROFILE) || defined(PROTO)
Karsten Hopp 0cf1c3
--- 22514,22533 ----
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  /*
Karsten Hopp 0cf1c3
   * Return TRUE if "name" looks like a builtin function name: starts with a
Karsten Hopp 0cf1c3
!  * lower case letter and doesn't contain AUTOLOAD_CHAR.
Karsten Hopp 0cf1c3
!  * "len" is the length of "name", or -1 for NUL terminated.
Karsten Hopp 0cf1c3
   */
Karsten Hopp 0cf1c3
      static int
Karsten Hopp 0cf1c3
! builtin_function(name, len)
Karsten Hopp 0cf1c3
      char_u *name;
Karsten Hopp 0cf1c3
+     int len;
Karsten Hopp 0cf1c3
  {
Karsten Hopp 0cf1c3
!     char_u *p;
Karsten Hopp 0cf1c3
! 
Karsten Hopp 0cf1c3
!     if (!ASCII_ISLOWER(name[0]))
Karsten Hopp 0cf1c3
! 	return FALSE;
Karsten Hopp 0cf1c3
!     p = vim_strchr(name, AUTOLOAD_CHAR);
Karsten Hopp 0cf1c3
!     return p == NULL || (len > 0 && p > name + len);
Karsten Hopp 0cf1c3
  }
Karsten Hopp 0cf1c3
  
Karsten Hopp 0cf1c3
  #if defined(FEAT_PROFILE) || defined(PROTO)
Karsten Hopp 0cf1c3
*** ../vim-7.4.259/src/testdir/test_eval.in	2014-04-05 21:28:50.667174384 +0200
Karsten Hopp 0cf1c3
--- src/testdir/test_eval.in	2014-04-23 17:35:12.086960858 +0200
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 144,149 ****
Karsten Hopp 0cf1c3
--- 144,167 ----
Karsten Hopp 0cf1c3
  :delcommand AR
Karsten Hopp 0cf1c3
  :call garbagecollect(1)
Karsten Hopp 0cf1c3
  :"
Karsten Hopp 0cf1c3
+ :" function name includes a colon
Karsten Hopp 0cf1c3
+ :try
Karsten Hopp 0cf1c3
+ :func! g:test()
Karsten Hopp 0cf1c3
+ :echo "test"
Karsten Hopp 0cf1c3
+ :endfunc
Karsten Hopp 0cf1c3
+ :catch
Karsten Hopp 0cf1c3
+ :$put =v:exception
Karsten Hopp 0cf1c3
+ :endtry
Karsten Hopp 0cf1c3
+ :"
Karsten Hopp 0cf1c3
+ :" function name folowed by #
Karsten Hopp 0cf1c3
+ :try
Karsten Hopp 0cf1c3
+ :func! test2() "#
Karsten Hopp 0cf1c3
+ :echo "test2"
Karsten Hopp 0cf1c3
+ :endfunc
Karsten Hopp 0cf1c3
+ :catch
Karsten Hopp 0cf1c3
+ :$put =v:exception
Karsten Hopp 0cf1c3
+ :endtry
Karsten Hopp 0cf1c3
+ :"
Karsten Hopp 0cf1c3
  :/^start:/+1,$wq! test.out
Karsten Hopp 0cf1c3
  :" vim: et ts=4 isk-=\: fmr=???,???
Karsten Hopp 0cf1c3
  :call getchar()
Karsten Hopp 0cf1c3
*** ../vim-7.4.259/src/testdir/test_eval.ok	2014-04-05 21:28:50.667174384 +0200
Karsten Hopp 0cf1c3
--- src/testdir/test_eval.ok	2014-04-23 17:36:34.602958870 +0200
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 335,337 ****
Karsten Hopp 0cf1c3
--- 335,339 ----
Karsten Hopp 0cf1c3
  Vim(call):E883: search pattern and expression register may not contain two or more lines
Karsten Hopp 0cf1c3
  Executing call setreg(1, ["", "", [], ""])
Karsten Hopp 0cf1c3
  Vim(call):E730: using List as a String
Karsten Hopp 0cf1c3
+ Vim(function):E128: Function name must start with a capital or "s:": g:test()
Karsten Hopp 0cf1c3
+ Vim(function):E128: Function name must start with a capital or "s:": test2() "#
Karsten Hopp 0cf1c3
*** ../vim-7.4.259/src/version.c	2014-04-23 12:52:36.499369426 +0200
Karsten Hopp 0cf1c3
--- src/version.c	2014-04-23 17:17:50.994985945 +0200
Karsten Hopp 0cf1c3
***************
Karsten Hopp 0cf1c3
*** 736,737 ****
Karsten Hopp 0cf1c3
--- 736,739 ----
Karsten Hopp 0cf1c3
  {   /* Add new patch number below this line */
Karsten Hopp 0cf1c3
+ /**/
Karsten Hopp 0cf1c3
+     260,
Karsten Hopp 0cf1c3
  /**/
Karsten Hopp 0cf1c3
Karsten Hopp 0cf1c3
-- 
Karsten Hopp 0cf1c3
From "know your smileys":
Karsten Hopp 0cf1c3
 ;-0	Can't find shift key
Karsten Hopp 0cf1c3
 ,-9	Kann Umschalttaste nicht finden
Karsten Hopp 0cf1c3
Karsten Hopp 0cf1c3
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 0cf1c3
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 0cf1c3
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 0cf1c3
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///