Patch 8.1.0515
Problem:    Reloading a script gives errors for existing functions.
Solution:   Allow redefining a function once when reloading a script.
Files:      src/testdir/test_functions.vim, src/userfunc.c, src/structs.h,
            src/globals.h, src/buffer.c, src/ex_cmds2.c, src/main.c,
            src/option.c, runtime/doc/eval.txt


*** ../vim-8.1.0514/src/testdir/test_functions.vim      2018-11-04 
23:39:33.953644902 +0100
--- src/testdir/test_functions.vim      2018-11-10 16:54:47.043813092 +0100
***************
*** 1138,1140 ****
--- 1138,1167 ----
    call delete('Xfuncrange2')
    bwipe!
  endfunc
+ 
+ func Test_func_exists_on_reload()
+   call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 
'Xfuncexists')
+   call assert_equal(0, exists('*ExistingFunction'))
+   source Xfuncexists
+   call assert_equal(1, exists('*ExistingFunction'))
+   " Redefining a function when reloading a script is OK.
+   source Xfuncexists
+   call assert_equal(1, exists('*ExistingFunction'))
+ 
+   " But redefining in another script is not OK.
+   call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 
'Xfuncexists2')
+   call assert_fails('source Xfuncexists2', 'E122:')
+ 
+   delfunc ExistingFunction
+   call assert_equal(0, exists('*ExistingFunction'))
+   call writefile([
+       \ 'func ExistingFunction()', 'echo "yes"', 'endfunc',
+       \ 'func ExistingFunction()', 'echo "no"', 'endfunc',
+       \ ], 'Xfuncexists')
+   call assert_fails('source Xfuncexists', 'E122:')
+   call assert_equal(1, exists('*ExistingFunction'))
+ 
+   call delete('Xfuncexists2')
+   call delete('Xfuncexists')
+   delfunc ExistingFunction
+ endfunc
*** ../vim-8.1.0514/src/userfunc.c      2018-11-04 23:39:33.953644902 +0100
--- src/userfunc.c      2018-11-10 16:48:35.046279419 +0100
***************
*** 2330,2343 ****
        fp = find_func(name);
        if (fp != NULL)
        {
!           if (!eap->forceit)
            {
                emsg_funcname(e_funcexts, name);
                goto erret;
            }
            if (fp->uf_calls > 0)
            {
!               emsg_funcname(N_("E127: Cannot redefine function %s: It is in 
use"),
                                                                        name);
                goto erret;
            }
--- 2330,2348 ----
        fp = find_func(name);
        if (fp != NULL)
        {
!           // Function can be replaced with "function!" and when sourcing the
!           // same script again, but only once.
!           if (!eap->forceit
!                       && (fp->uf_script_ctx.sc_sid != current_sctx.sc_sid
!                           || fp->uf_script_ctx.sc_seq == current_sctx.sc_seq))
            {
                emsg_funcname(e_funcexts, name);
                goto erret;
            }
            if (fp->uf_calls > 0)
            {
!               emsg_funcname(
!                       N_("E127: Cannot redefine function %s: It is in use"),
                                                                        name);
                goto erret;
            }
*** ../vim-8.1.0514/src/structs.h       2018-10-19 22:35:04.889189955 +0200
--- src/structs.h       2018-11-10 16:33:16.847566578 +0100
***************
*** 84,89 ****
--- 84,90 ----
   */
  typedef struct {
      scid_T    sc_sid;         // script ID
+     int               sc_seq;         // sourcing sequence number
      linenr_T  sc_lnum;        // line number
  } sctx_T;
  
*** ../vim-8.1.0514/src/globals.h       2018-09-13 15:33:39.609712174 +0200
--- src/globals.h       2018-11-10 16:33:30.455464981 +0100
***************
*** 326,332 ****
  EXTERN int    garbage_collect_at_exit INIT(= FALSE);
  
  // Script CTX being sourced or was sourced to define the current function.
! EXTERN sctx_T current_sctx INIT(= {0 COMMA 0});
  #endif
  
  EXTERN int    did_source_packages INIT(= FALSE);
--- 326,332 ----
  EXTERN int    garbage_collect_at_exit INIT(= FALSE);
  
  // Script CTX being sourced or was sourced to define the current function.
! EXTERN sctx_T current_sctx INIT(= {0 COMMA 0 COMMA 0});
  #endif
  
  EXTERN int    did_source_packages INIT(= FALSE);
*** ../vim-8.1.0514/src/buffer.c        2018-10-11 19:27:43.916066156 +0200
--- src/buffer.c        2018-11-10 16:34:17.031116881 +0100
***************
*** 5519,5524 ****
--- 5519,5525 ----
  #ifdef FEAT_EVAL
                save_current_sctx = current_sctx;
                current_sctx.sc_sid = SID_MODELINE;
+               current_sctx.sc_seq = 0;
                current_sctx.sc_lnum = 0;
  #endif
                retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
*** ../vim-8.1.0514/src/ex_cmds2.c      2018-11-05 20:25:48.804089622 +0100
--- src/ex_cmds2.c      2018-11-10 16:39:27.217457068 +0100
***************
*** 4344,4349 ****
--- 4344,4350 ----
  #ifdef FEAT_EVAL
      sctx_T                save_current_sctx;
      static scid_T         last_current_SID = 0;
+     static int                    last_current_SID_seq = 0;
      funccal_entry_T       funccalp_entry;
      int                           save_debug_break_level = debug_break_level;
      scriptitem_T          *si = NULL;
***************
*** 4508,4518 ****
       * Also starts profiling timer for nested script. */
      save_funccal(&funccalp_entry);
  
!     /*
!      * Check if this script was sourced before to finds its SID.
!      * If it's new, generate a new SID.
!      */
      save_current_sctx = current_sctx;
      current_sctx.sc_lnum = 0;
  # ifdef UNIX
      stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
--- 4509,4519 ----
       * Also starts profiling timer for nested script. */
      save_funccal(&funccalp_entry);
  
!     // Check if this script was sourced before to finds its SID.
!     // If it's new, generate a new SID.
!     // Always use a new sequence number.
      save_current_sctx = current_sctx;
+     current_sctx.sc_seq = ++last_current_SID_seq;
      current_sctx.sc_lnum = 0;
  # ifdef UNIX
      stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
*** ../vim-8.1.0514/src/main.c  2018-10-14 21:40:57.356848425 +0200
--- src/main.c  2018-11-10 16:42:21.260538735 +0100
***************
*** 2953,2958 ****
--- 2953,2959 ----
      sourcing_name = (char_u *)"command line";
  #ifdef FEAT_EVAL
      current_sctx.sc_sid = SID_CARG;
+     current_sctx.sc_seq = 0;
  #endif
      for (i = 0; i < parmp->n_commands; ++i)
      {
***************
*** 3183,3188 ****
--- 3184,3190 ----
  #ifdef FEAT_EVAL
        save_current_sctx = current_sctx;
        current_sctx.sc_sid = SID_ENV;
+       current_sctx.sc_seq = 0;
        current_sctx.sc_lnum = 0;
  #endif
        do_cmdline_cmd(initstr);
*** ../vim-8.1.0514/src/option.c        2018-11-04 14:40:42.347139567 +0100
--- src/option.c        2018-11-10 16:48:26.810332143 +0100
***************
*** 415,421 ****
      char_u    *def_val[2];    // default values for variable (vi and vim)
  #ifdef FEAT_EVAL
      sctx_T    script_ctx;     // script context where the option was last set
! # define SCTX_INIT , {0, 0}
  #else
  # define SCTX_INIT
  #endif
--- 415,421 ----
      char_u    *def_val[2];    // default values for variable (vi and vim)
  #ifdef FEAT_EVAL
      sctx_T    script_ctx;     // script context where the option was last set
! # define SCTX_INIT , {0, 0, 0}
  #else
  # define SCTX_INIT
  #endif
***************
*** 5959,5964 ****
--- 5959,5965 ----
            else
            {
                script_ctx.sc_sid = set_sid;
+               script_ctx.sc_seq = 0;
                script_ctx.sc_lnum = 0;
            }
            set_option_sctx_idx(idx, opt_flags, script_ctx);
*** ../vim-8.1.0514/runtime/doc/eval.txt        2018-10-25 12:30:52.270659874 
+0200
--- runtime/doc/eval.txt        2018-11-10 16:52:02.836919520 +0100
***************
*** 9658,9666 ****
                        deleted if there are no more references to it.
                                                                *E127* *E122*
                        When a function by this name already exists and [!] is
!                       not used an error message is given.  When [!] is used,
!                       an existing function is silently replaced.  Unless it
!                       is currently being executed, that is an error.
                        NOTE: Use ! wisely.  If used without care it can cause
                        an existing function to be replaced unexpectedly,
                        which is hard to debug.
--- 9673,9685 ----
                        deleted if there are no more references to it.
                                                                *E127* *E122*
                        When a function by this name already exists and [!] is
!                       not used an error message is given.  There is one
!                       exception: When sourcing a script again, a function
!                       that was previously defined in that script will be
!                       silently replaced.
!                       When [!] is used, an existing function is silently
!                       replaced.  Unless it is currently being executed, that
!                       is an error.
                        NOTE: Use ! wisely.  If used without care it can cause
                        an existing function to be replaced unexpectedly,
                        which is hard to debug.
*** ../vim-8.1.0514/src/version.c       2018-11-10 16:01:23.335381858 +0100
--- src/version.c       2018-11-10 16:26:16.190674882 +0100
***************
*** 794,795 ****
--- 794,797 ----
  {   /* Add new patch number below this line */
+ /**/
+     515,
  /**/

-- 
Witches prefer brooms: vacuum-cleaners need extension cords!

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
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/d/optout.

Raspunde prin e-mail lui