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.