Patch 9.0.0476
Problem:    Varargs does not work for replacement function of substitute().
Solution:   Check the varargs flag of the function. (closes #11142)
Files:      src/regexp.c, src/structs.h, src/userfunc.c,
            src/testdir/test_substitute.vim


*** ../vim-9.0.0475/src/regexp.c        2022-08-26 21:33:00.662738976 +0100
--- src/regexp.c        2022-09-16 12:07:49.350014550 +0100
***************
*** 1817,1830 ****
   * call_func() by vim_regsub_both().
   */
      static int
! fill_submatch_list(int argc UNUSED, typval_T *argv, int argskip, int argcount)
  {
      listitem_T        *li;
      int               i;
      char_u    *s;
      typval_T  *listarg = argv + argskip;
  
!     if (argcount == argskip)
        // called function doesn't take a submatches argument
        return argskip;
  
--- 1817,1830 ----
   * call_func() by vim_regsub_both().
   */
      static int
! fill_submatch_list(int argc UNUSED, typval_T *argv, int argskip, ufunc_T *fp)
  {
      listitem_T        *li;
      int               i;
      char_u    *s;
      typval_T  *listarg = argv + argskip;
  
!     if (!fp->uf_varargs && fp->uf_args.ga_len <= argskip)
        // called function doesn't take a submatches argument
        return argskip;
  
*** ../vim-9.0.0475/src/structs.h       2022-09-14 00:30:47.077316538 +0100
--- src/structs.h       2022-09-16 11:49:45.861095933 +0100
***************
*** 2052,2064 ****
  
  // Struct passed between functions dealing with function call execution.
  //
! // "argv_func", when not NULL, can be used to fill in arguments only when the
  // invoked function uses them.  It is called like this:
! //   new_argcount = argv_func(current_argcount, argv, partial_argcount,
! //                                                    called_func_argcount)
  //
  typedef struct {
!     int               (* fe_argv_func)(int, typval_T *, int, int);
      linenr_T  fe_firstline;   // first line of range
      linenr_T  fe_lastline;    // last line of range
      int               *fe_doesrange;  // if not NULL: return: function 
handled range
--- 2052,2064 ----
  
  // Struct passed between functions dealing with function call execution.
  //
! // "fe_argv_func", when not NULL, can be used to fill in arguments only when 
the
  // invoked function uses them.  It is called like this:
! //   new_argcount = fe_argv_func(current_argcount, argv, partial_argcount,
! //                                                    called_func)
  //
  typedef struct {
!     int               (* fe_argv_func)(int, typval_T *, int, ufunc_T *);
      linenr_T  fe_firstline;   // first line of range
      linenr_T  fe_lastline;    // last line of range
      int               *fe_doesrange;  // if not NULL: return: function 
handled range
*** ../vim-9.0.0475/src/userfunc.c      2022-09-08 19:51:39.730308347 +0100
--- src/userfunc.c      2022-09-16 11:49:45.865095884 +0100
***************
*** 3644,3650 ****
                if (funcexe->fe_argv_func != NULL)
                    // postponed filling in the arguments, do it now
                    argcount = funcexe->fe_argv_func(argcount, argvars,
!                                              argv_clear, fp->uf_args.ga_len);
  
                if (funcexe->fe_basetv != NULL)
                {
--- 3644,3650 ----
                if (funcexe->fe_argv_func != NULL)
                    // postponed filling in the arguments, do it now
                    argcount = funcexe->fe_argv_func(argcount, argvars,
!                                              argv_clear, fp);
  
                if (funcexe->fe_basetv != NULL)
                {
*** ../vim-9.0.0475/src/testdir/test_substitute.vim     2022-09-13 
13:45:09.802461528 +0100
--- src/testdir/test_substitute.vim     2022-09-16 12:07:15.798145387 +0100
***************
*** 439,458 ****
  func SubReplacer(text, submatches)
    return a:text .. a:submatches[0] .. a:text
  endfunc
  func SubReplacer20(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, 
t14, t15, t16, t17, t18, t19, submatches)
    return a:t3 .. a:submatches[0] .. a:t11
  endfunc
  
  func Test_substitute_partial()
!    call assert_equal('1foo2foo3', substitute('123', '2', 
function('SubReplacer', ['foo']), 'g'))
  
!    " 19 arguments plus one is just OK
!    let Replacer = function('SubReplacer20', repeat(['foo'], 19))
!    call assert_equal('1foo2foo3', substitute('123', '2', Replacer, 'g'))
  
!    " 20 arguments plus one is too many
!    let Replacer = function('SubReplacer20', repeat(['foo'], 20))
!    call assert_fails("call substitute('123', '2', Replacer, 'g')", 'E118:')
  endfunc
  
  func Test_substitute_float()
--- 439,462 ----
  func SubReplacer(text, submatches)
    return a:text .. a:submatches[0] .. a:text
  endfunc
+ func SubReplacerVar(text, ...)
+   return a:text .. a:1[0] .. a:text
+ endfunc
  func SubReplacer20(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, 
t14, t15, t16, t17, t18, t19, submatches)
    return a:t3 .. a:submatches[0] .. a:t11
  endfunc
  
  func Test_substitute_partial()
!   call assert_equal('1foo2foo3', substitute('123', '2', 
function('SubReplacer', ['foo']), 'g'))
!   call assert_equal('1foo2foo3', substitute('123', '2', 
function('SubReplacerVar', ['foo']), 'g'))
  
!   " 19 arguments plus one is just OK
!   let Replacer = function('SubReplacer20', repeat(['foo'], 19))
!   call assert_equal('1foo2foo3', substitute('123', '2', Replacer, 'g'))
  
!   " 20 arguments plus one is too many
!   let Replacer = function('SubReplacer20', repeat(['foo'], 20))
!   call assert_fails("call substitute('123', '2', Replacer, 'g')", 'E118:')
  endfunc
  
  func Test_substitute_float()
*** ../vim-9.0.0475/src/version.c       2022-09-15 22:26:13.166294520 +0100
--- src/version.c       2022-09-16 12:09:09.205712508 +0100
***************
*** 705,706 ****
--- 705,708 ----
  {   /* Add new patch number below this line */
+ /**/
+     476,
  /**/

-- 
>From "know your smileys":
 :~)    A man with a tape recorder up his nose

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220916111057.85B541C0846%40moolenaar.net.

Raspunde prin e-mail lui