summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2007-01-14 14:28:34 +0000
committerBram Moolenaar <Bram@vim.org>2007-01-14 14:28:34 +0000
commit863b53b72e50508b766c83678a0bd390d5a5f585 (patch)
tree36acc28d09a10724dbadbdd1be49a19287bc1f92
parent89ed3dfd87f2fa28037743b187ba706804c81a44 (diff)
downloadvim-863b53b72e50508b766c83678a0bd390d5a5f585.zip
updated for version 7.0-183
-rw-r--r--src/eval.c59
-rw-r--r--src/version.c2
2 files changed, 36 insertions, 25 deletions
diff --git a/src/eval.c b/src/eval.c
index f9177b3b3..30f163599 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -898,6 +898,7 @@ set_internal_string_var(name, value)
}
static lval_T *redir_lval = NULL;
+static garray_T redir_ga; /* only valid when redir_lval is not NULL */
static char_u *redir_endp = NULL;
static char_u *redir_varname = NULL;
@@ -932,6 +933,9 @@ var_redir_start(name, append)
return FAIL;
}
+ /* The output is stored in growarray "redir_ga" until redirection ends. */
+ ga_init2(&redir_ga, (int)sizeof(char), 500);
+
/* Parse the variable name (can be a dict or list entry). */
redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE,
FNE_CHECK_START);
@@ -974,42 +978,36 @@ var_redir_start(name, append)
}
/*
- * Append "value[len]" to the variable set by var_redir_start().
+ * Append "value[value_len]" to the variable set by var_redir_start().
+ * The actual appending is postponed until redirection ends, because the value
+ * appended may in fact be the string we write to, changing it may cause freed
+ * memory to be used:
+ * :redir => foo
+ * :let foo
+ * :redir END
*/
void
-var_redir_str(value, len)
+var_redir_str(value, value_len)
char_u *value;
- int len;
+ int value_len;
{
- char_u *val;
- typval_T tv;
- int save_emsg;
- int err;
+ size_t len;
if (redir_lval == NULL)
return;
- if (len == -1)
- /* Append the entire string */
- val = vim_strsave(value);
+ if (value_len == -1)
+ len = STRLEN(value); /* Append the entire string */
else
- /* Append only the specified number of characters */
- val = vim_strnsave(value, len);
- if (val == NULL)
- return;
-
- tv.v_type = VAR_STRING;
- tv.vval.v_string = val;
+ len = value_len; /* Append only "value_len" characters */
- save_emsg = did_emsg;
- did_emsg = FALSE;
- set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
- err = did_emsg;
- did_emsg |= save_emsg;
- if (err)
+ if (ga_grow(&redir_ga, (int)len) == OK)
+ {
+ mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
+ redir_ga.ga_len += len;
+ }
+ else
var_redir_stop();
-
- vim_free(tv.vval.v_string);
}
/*
@@ -1018,8 +1016,19 @@ var_redir_str(value, len)
void
var_redir_stop()
{
+ typval_T tv;
+
if (redir_lval != NULL)
{
+ /* Append the trailing NUL. */
+ ga_append(&redir_ga, NUL);
+
+ /* Assign the text to the variable. */
+ tv.v_type = VAR_STRING;
+ tv.vval.v_string = redir_ga.ga_data;
+ set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
+ vim_free(tv.vval.v_string);
+
clear_lval(redir_lval);
vim_free(redir_lval);
redir_lval = NULL;
diff --git a/src/version.c b/src/version.c
index db1d34fd5..36b2f94d5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -667,6 +667,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 183,
+/**/
182,
/**/
181,