summaryrefslogtreecommitdiffstats
path: root/src/evalvars.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-05-10 13:24:30 +0100
committerBram Moolenaar <Bram@vim.org>2022-05-10 13:24:30 +0100
commit0abc2871c105882ed1c1effb9a7757fad8a395bd (patch)
tree0377e3f47b0fda6713cc0e8b6426616457e07912 /src/evalvars.c
parent57ff52677bf5ba1651281ffe40505df8feba4a36 (diff)
patch 8.2.4930: interpolated string expression requires escapingv8.2.4930
Problem: Interpolated string expression requires escaping. Solution: Do not require escaping in the expression.
Diffstat (limited to 'src/evalvars.c')
-rw-r--r--src/evalvars.c74
1 files changed, 43 insertions, 31 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index 2f285189b6..d8ee216084 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -603,16 +603,52 @@ list_script_vars(int *first)
}
/*
- * Evaluate all the Vim expressions ({expr}) in string "str" and return the
- * resulting string. The caller must free the returned string.
+ * Evaluate one Vim expression {expr} in string "p" and append the
+ * resulting string to "gap". "p" points to the opening "{".
+ * Return a pointer to the character after "}", NULL for an error.
+ */
+ char_u *
+eval_one_expr_in_str(char_u *p, garray_T *gap)
+{
+ char_u *block_start = skipwhite(p + 1); // skip the opening {
+ char_u *block_end = block_start;
+ char_u *expr_val;
+
+ if (*block_start == NUL)
+ {
+ semsg(_(e_missing_close_curly_str), p);
+ return NULL;
+ }
+ if (skip_expr(&block_end, NULL) == FAIL)
+ return NULL;
+ block_end = skipwhite(block_end);
+ if (*block_end != '}')
+ {
+ semsg(_(e_missing_close_curly_str), p);
+ return NULL;
+ }
+ *block_end = NUL;
+ expr_val = eval_to_string(block_start, TRUE);
+ *block_end = '}';
+ if (expr_val == NULL)
+ return NULL;
+ ga_concat(gap, expr_val);
+ vim_free(expr_val);
+
+ return block_end + 1;
+}
+
+/*
+ * Evaluate all the Vim expressions {expr} in "str" and return the resulting
+ * string in allocated memory. "{{" is reduced to "{" and "}}" to "}".
+ * Used for a heredoc assignment.
+ * Returns NULL for an error.
*/
char_u *
eval_all_expr_in_str(char_u *str)
{
garray_T ga;
char_u *p;
- char_u save_c;
- char_u *expr_val;
ga_init2(&ga, 1, 80);
p = str;
@@ -620,8 +656,6 @@ eval_all_expr_in_str(char_u *str)
while (*p != NUL)
{
char_u *lit_start;
- char_u *block_start;
- char_u *block_end;
int escaped_brace = FALSE;
// Look for a block start.
@@ -656,35 +690,13 @@ eval_all_expr_in_str(char_u *str)
continue;
}
- // Skip the opening {.
- block_start = ++p;
- block_end = block_start;
- if (*block_start != NUL && skip_expr(&block_end, NULL) == FAIL)
- {
- ga_clear(&ga);
- return NULL;
- }
- block_end = skipwhite(block_end);
- // The block must be closed by a }.
- if (*block_end != '}')
- {
- semsg(_(e_missing_close_curly_str), str);
- ga_clear(&ga);
- return NULL;
- }
- save_c = *block_end;
- *block_end = NUL;
- expr_val = eval_to_string(block_start, TRUE);
- *block_end = save_c;
- if (expr_val == NULL)
+ // Evaluate the expression and append the result.
+ p = eval_one_expr_in_str(p, &ga);
+ if (p == NULL)
{
ga_clear(&ga);
return NULL;
}
- ga_concat(&ga, expr_val);
- vim_free(expr_val);
-
- p = block_end + 1;
}
ga_append(&ga, NUL);