> I managed to make the test files work, guessing the missing characters.
> 
> The remark about get_tv_string_chk() remains.  Can you please look into
> fixing that?

Since I have no idea what setreg(regname, [number]) may be used for the easiest 
fix is the one that just forbids using numbers.

Alternative approaches:
1. Second easiest to code: just vim_strsave() every string from 
get_tv_string_chk and free it afterwards.
2. Rather fast: use own buffer, if get_tv_string_buf_chk returned it then do 
vim_strsave(). Comes at a cost of doubling lstval size and one additional alloc 
per each number.
3. Use register appending each time number was found.

Approach used in patch: 2. Wanted to post both 0. and 2. approaches, but diffs 
for the 0. got screwed up and I mentioned this only after this happened.

Found another problem: setreg('z', []) returns E341 (tries to allocate zero 
bytes). Should probably be used to unset register/set it to an empty string.

# HG changeset patch
# User ZyX <[email protected]>
# Date 1396645333 -14400
#      Sat Apr 05 01:02:13 2014 +0400
# Node ID ef30fcd05203feee8ca40a23ac75eed55549c681
# Parent  8bf05884266be337087b025d22ce7aad0b8a29ec
Fix problem reported by Bram

diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -16823,24 +16823,34 @@
     if (argvars[1].v_type == VAR_LIST)
     {
        char_u          **lstval;
+       char_u          **allocval;
+       char_u          buf[NUMBUFLEN];
        char_u          **curval;
+       char_u          **curallocval;
        int             len = argvars[1].vval.v_list->lv_len;
        listitem_T      *li;
 
-       lstval = (char_u **)alloc(sizeof(char_u *) * (len + 1));
+       lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2));
        if (lstval == NULL)
            return;
+       allocval = lstval + len + 2;
        curval = lstval;
+       curallocval = allocval;
+       *curallocval = NULL;
 
        for (li = argvars[1].vval.v_list->lv_first; li != NULL;
                                                             li = li->li_next)
        {
-           /* TODO: this may use a static buffer several times. */
-           strval = get_tv_string_chk(&li->li_tv);
+           strval = get_tv_string_buf_chk(&li->li_tv, buf);
            if (strval == NULL)
-           {
-               vim_free(lstval);
-               return;
+               goto free_lstval;
+           if (strval == buf)
+           {
+               strval = vim_strsave(buf);
+               if (strval == NULL)
+                   goto free_lstval;
+               *curallocval++ = strval;
+               *curallocval = NULL;
            }
            *curval++ = strval;
        }
@@ -16848,6 +16858,10 @@
 
        write_reg_contents_lst(regname, lstval, -1,
                                                append, yank_type, block_len);
+free_lstval:
+       if (*allocval != NULL)
+           for (curallocval = allocval; *curallocval != NULL; curallocval++)
+               vim_free(*curallocval);
        vim_free(lstval);
     }
     else
diff --git a/src/testdir/test_eval.in b/src/testdir/test_eval.in
--- a/src/testdir/test_eval.in
+++ b/src/testdir/test_eval.in
@@ -90,6 +90,8 @@
 call SetReg('b', ['abcB3'], 'l')
 call SetReg('c', ['abcC3'], 'b')
 call SetReg('d', ['abcD3'])
+call SetReg('e', [1, 2, 'abc', 3])
+call SetReg('f', [1, 2, 3])
 
 $put ='{{{1 Appending lists with setreg()'
 call SetReg('A', ['abcA3c'], 'c')
@@ -128,8 +130,8 @@
 call ErrExe('call setreg([], 2)')
 call ErrExe('call setreg(1, {})')
 call ErrExe('call setreg(1, 2, [])')
-call ErrExe('call setreg("/", [1, 2])')
-call ErrExe('call setreg("=", [1, 2])')
+call ErrExe('call setreg("/", ["1", "2"])')
+call ErrExe('call setreg("=", ["1", "2"])')
 call ErrExe('call setreg(1, ["", "", [], ""])')
 endfun
 :"
@@ -143,6 +145,7 @@
 :call garbagecollect(1)
 :"
 :/^start:/+1,$wq! test.out
+:while getchar(0)|endwhile
 :" vim: et ts=4 isk-=\: fmr=???,???
 :call getchar()
 ENDTEST
diff --git a/src/testdir/test_eval.ok b/src/testdir/test_eval.ok
index 
7fe5f1bd1b2745600d74f4bb8a86e7fa1391f607..267f9b0b1353682e17f1eedb2982c5d6d40dab84
GIT binary patch
literal 10418
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

-- 
-- 
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.
diff -crN -a vim-small-patches.8bf05884266b/src/eval.c vim-small-patches.ef30fcd05203/src/eval.c
*** vim-small-patches.8bf05884266b/src/eval.c	2014-04-05 01:07:29.619927130 +0400
--- vim-small-patches.ef30fcd05203/src/eval.c	2014-04-05 01:07:29.639927130 +0400
***************
*** 16823,16846 ****
      if (argvars[1].v_type == VAR_LIST)
      {
  	char_u		**lstval;
  	char_u		**curval;
  	int		len = argvars[1].vval.v_list->lv_len;
  	listitem_T	*li;
  
! 	lstval = (char_u **)alloc(sizeof(char_u *) * (len + 1));
  	if (lstval == NULL)
  	    return;
  	curval = lstval;
  
  	for (li = argvars[1].vval.v_list->lv_first; li != NULL;
  							     li = li->li_next)
  	{
! 	    /* TODO: this may use a static buffer several times. */
! 	    strval = get_tv_string_chk(&li->li_tv);
  	    if (strval == NULL)
  	    {
! 		vim_free(lstval);
! 		return;
  	    }
  	    *curval++ = strval;
  	}
--- 16823,16856 ----
      if (argvars[1].v_type == VAR_LIST)
      {
  	char_u		**lstval;
+ 	char_u		**allocval;
+ 	char_u		buf[NUMBUFLEN];
  	char_u		**curval;
+ 	char_u		**curallocval;
  	int		len = argvars[1].vval.v_list->lv_len;
  	listitem_T	*li;
  
! 	lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2));
  	if (lstval == NULL)
  	    return;
+ 	allocval = lstval + len + 2;
  	curval = lstval;
+ 	curallocval = allocval;
+ 	*curallocval = NULL;
  
  	for (li = argvars[1].vval.v_list->lv_first; li != NULL;
  							     li = li->li_next)
  	{
! 	    strval = get_tv_string_buf_chk(&li->li_tv, buf);
  	    if (strval == NULL)
+ 		goto free_lstval;
+ 	    if (strval == buf)
  	    {
! 		strval = vim_strsave(buf);
! 		if (strval == NULL)
! 		    goto free_lstval;
! 		*curallocval++ = strval;
! 		*curallocval = NULL;
  	    }
  	    *curval++ = strval;
  	}
***************
*** 16848,16853 ****
--- 16858,16867 ----
  
  	write_reg_contents_lst(regname, lstval, -1,
  						append, yank_type, block_len);
+ free_lstval:
+ 	if (*allocval != NULL)
+ 	    for (curallocval = allocval; *curallocval != NULL; curallocval++)
+ 		vim_free(*curallocval);
  	vim_free(lstval);
      }
      else
diff -crN -a vim-small-patches.8bf05884266b/src/testdir/test_eval.in vim-small-patches.ef30fcd05203/src/testdir/test_eval.in
*** vim-small-patches.8bf05884266b/src/testdir/test_eval.in	2014-04-05 01:07:29.619927130 +0400
--- vim-small-patches.ef30fcd05203/src/testdir/test_eval.in	2014-04-05 01:07:29.639927130 +0400
***************
*** 90,95 ****
--- 90,97 ----
  call SetReg('b', ['abcB3'], 'l')
  call SetReg('c', ['abcC3'], 'b')
  call SetReg('d', ['abcD3'])
+ call SetReg('e', [1, 2, 'abc', 3])
+ call SetReg('f', [1, 2, 3])
  
  $put ='{{{1 Appending lists with setreg()'
  call SetReg('A', ['abcA3c'], 'c')
***************
*** 128,135 ****
  call ErrExe('call setreg([], 2)')
  call ErrExe('call setreg(1, {})')
  call ErrExe('call setreg(1, 2, [])')
! call ErrExe('call setreg("/", [1, 2])')
! call ErrExe('call setreg("=", [1, 2])')
  call ErrExe('call setreg(1, ["", "", [], ""])')
  endfun
  :"
--- 130,137 ----
  call ErrExe('call setreg([], 2)')
  call ErrExe('call setreg(1, {})')
  call ErrExe('call setreg(1, 2, [])')
! call ErrExe('call setreg("/", ["1", "2"])')
! call ErrExe('call setreg("=", ["1", "2"])')
  call ErrExe('call setreg(1, ["", "", [], ""])')
  endfun
  :"
***************
*** 143,148 ****
--- 145,151 ----
  :call garbagecollect(1)
  :"
  :/^start:/+1,$wq! test.out
+ :while getchar(0)|endwhile
  :" vim: et ts=4 isk-=\: fmr=???,???
  :call getchar()
  ENDTEST
diff -crN -a vim-small-patches.8bf05884266b/src/testdir/test_eval.ok vim-small-patches.ef30fcd05203/src/testdir/test_eval.ok
*** vim-small-patches.8bf05884266b/src/testdir/test_eval.ok	2014-04-05 01:07:29.619927130 +0400
--- vim-small-patches.ef30fcd05203/src/testdir/test_eval.ok	2014-04-05 01:07:29.639927130 +0400
***************
*** 314,322 ****
  Vim(call):E731: using Dictionary as a String
  Executing call setreg(1, 2, [])
  Vim(call):E730: using List as a String
! Executing call setreg("/", [1, 2])
  Vim(call):E883: search pattern and expression register may not contain two or more lines
! Executing call setreg("=", [1, 2])
  Vim(call):E883: search pattern and expression register may not contain two or more lines
  Executing call setreg(1, ["", "", [], ""])
! Vim(call):E730: using List as a String
--- 314,324 ----
  Vim(call):E731: using Dictionary as a String
  Executing call setreg(1, 2, [])
  Vim(call):E730: using List as a String
! Executing call setreg("/", ["1", "2"])
  Vim(call):E883: search pattern and expression register may not contain two or more lines
! Executing call setreg("=", ["1", "2"])
  Vim(call):E883: search pattern and expression register may not contain two or more lines
  Executing call setreg(1, ["", "", [], ""])
! Vim(call):E898: List may only contain string values
! Executing call setreg("z", [1, 2, 3])
! Vim(call):E898: List may only contain string values

Raspunde prin e-mail lui