summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2014-04-05 21:28:56 +0200
committerBram Moolenaar <Bram@vim.org>2014-04-05 21:28:56 +0200
commit7d647820ed7c747bbc5618366ce6dfcf0006398d (patch)
tree6a98a72a5ee41c50775517d57bc853bdfac24fe5 /src
parent39c29ed5118ab513554d1d51d6a98e65f32784ba (diff)
downloadvim-git-7d647820ed7c747bbc5618366ce6dfcf0006398d.tar.gz
updated for version 7.4.249v7.4.249
Problem: Using setreg() with a list of numbers does not work. Solution: Use a separate buffer for numbers. (ZyX)
Diffstat (limited to 'src')
-rw-r--r--src/eval.c28
-rw-r--r--src/testdir/test_eval.in6
-rw-r--r--src/testdir/test_eval.okbin10307 -> 10578 bytes
-rw-r--r--src/version.c2
4 files changed, 29 insertions, 7 deletions
diff --git a/src/eval.c b/src/eval.c
index be8d4da3e..2014deb80 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -16827,24 +16827,36 @@ f_setreg(argvars, rettv)
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));
+ /* First half: use for pointers to result lines; second half: use for
+ * pointers to allocated copies. */
+ lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2));
if (lstval == NULL)
return;
curval = lstval;
+ allocval = lstval + len + 2;
+ curallocval = allocval;
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)
+ goto free_lstval;
+ if (strval == buf)
{
- vim_free(lstval);
- return;
+ /* Need to make a copy, next get_tv_string_buf_chk() will
+ * overwrite the string. */
+ strval = vim_strsave(buf);
+ if (strval == NULL)
+ goto free_lstval;
+ *curallocval++ = strval;
}
*curval++ = strval;
}
@@ -16852,6 +16864,9 @@ f_setreg(argvars, rettv)
write_reg_contents_lst(regname, lstval, -1,
append, yank_type, block_len);
+free_lstval:
+ while (curallocval > allocval)
+ vim_free(*--curallocval);
vim_free(lstval);
}
else
@@ -20453,6 +20468,9 @@ get_tv_string_buf(varp, buf)
return res != NULL ? res : (char_u *)"";
}
+/*
+ * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
+ */
char_u *
get_tv_string_chk(varp)
typval_T *varp;
diff --git a/src/testdir/test_eval.in b/src/testdir/test_eval.in
index 0a7ede695..b102be2b1 100644
--- a/src/testdir/test_eval.in
+++ b/src/testdir/test_eval.in
@@ -90,6 +90,8 @@ call SetReg('a', ['abcA3'], 'c')
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(1, 2, 3, 4)')
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
:"
diff --git a/src/testdir/test_eval.ok b/src/testdir/test_eval.ok
index 7fe5f1bd1..061e0cfd2 100644
--- a/src/testdir/test_eval.ok
+++ b/src/testdir/test_eval.ok
Binary files differ
diff --git a/src/version.c b/src/version.c
index eaa74cd17..c00210730 100644
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 249,
+/**/
248,
/**/
247,