Mercurial > vim
comparison src/vim9expr.c @ 28813:3626ca6a20ea v8.2.4930
patch 8.2.4930: interpolated string expression requires escaping
Commit: https://github.com/vim/vim/commit/0abc2871c105882ed1c1effb9a7757fad8a395bd
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue May 10 13:24:30 2022 +0100
patch 8.2.4930: interpolated string expression requires escaping
Problem: Interpolated string expression requires escaping.
Solution: Do not require escaping in the expression.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 10 May 2022 14:30:04 +0200 |
parents | 723c7d940cba |
children | bf013128ccf4 |
comparison
equal
deleted
inserted
replaced
28812:483371d05cd5 | 28813:3626ca6a20ea |
---|---|
760 int is_has = **arg == 'h'; | 760 int is_has = **arg == 'h'; |
761 int is_len = **arg == 'l'; | 761 int is_len = **arg == 'l'; |
762 | 762 |
763 argvars[0].v_type = VAR_UNKNOWN; | 763 argvars[0].v_type = VAR_UNKNOWN; |
764 if (*s == '"') | 764 if (*s == '"') |
765 (void)eval_string(&s, &argvars[0], TRUE); | 765 (void)eval_string(&s, &argvars[0], TRUE, FALSE); |
766 else if (*s == '\'') | 766 else if (*s == '\'') |
767 (void)eval_lit_string(&s, &argvars[0], TRUE); | 767 (void)eval_lit_string(&s, &argvars[0], TRUE, FALSE); |
768 s = skipwhite(s); | 768 s = skipwhite(s); |
769 if (*s == ')' && argvars[0].v_type == VAR_STRING | 769 if (*s == ')' && argvars[0].v_type == VAR_STRING |
770 && ((is_has && !dynamic_feature(argvars[0].vval.v_string)) | 770 && ((is_has && !dynamic_feature(argvars[0].vval.v_string)) |
771 || !is_has)) | 771 || !is_has)) |
772 { | 772 { |
1373 vim_free(name); | 1373 vim_free(name); |
1374 return ret; | 1374 return ret; |
1375 } | 1375 } |
1376 | 1376 |
1377 /* | 1377 /* |
1378 * Compile "$"string"" or "$'string'". | 1378 * Compile $"string" or $'string'. |
1379 */ | 1379 */ |
1380 static int | 1380 static int |
1381 compile_interp_string(char_u **arg, cctx_T *cctx) | 1381 compile_interp_string(char_u **arg, cctx_T *cctx) |
1382 { | 1382 { |
1383 typval_T tv; | 1383 typval_T tv; |
1384 int ret; | 1384 int ret; |
1385 int quote; | |
1385 int evaluate = cctx->ctx_skip != SKIP_YES; | 1386 int evaluate = cctx->ctx_skip != SKIP_YES; |
1386 | 1387 int count = 0; |
1387 // *arg is on the '$' character. | 1388 char_u *p; |
1388 (*arg)++; | 1389 |
1389 | 1390 // *arg is on the '$' character, move it to the first string character. |
1390 if (**arg == '"') | 1391 ++*arg; |
1391 ret = eval_string(arg, &tv, evaluate); | 1392 quote = **arg; |
1392 else | 1393 ++*arg; |
1393 ret = eval_lit_string(arg, &tv, evaluate); | 1394 |
1395 for (;;) | |
1396 { | |
1397 // Get the string up to the matching quote or to a single '{'. | |
1398 // "arg" is advanced to either the quote or the '{'. | |
1399 if (quote == '"') | |
1400 ret = eval_string(arg, &tv, evaluate, TRUE); | |
1401 else | |
1402 ret = eval_lit_string(arg, &tv, evaluate, TRUE); | |
1403 if (ret == FAIL) | |
1404 break; | |
1405 if (evaluate) | |
1406 { | |
1407 if ((tv.vval.v_string != NULL && *tv.vval.v_string != NUL) | |
1408 || (**arg != '{' && count == 0)) | |
1409 { | |
1410 // generate non-empty string or empty string if it's the only | |
1411 // one | |
1412 if (generate_PUSHS(cctx, &tv.vval.v_string) == FAIL) | |
1413 return FAIL; | |
1414 tv.vval.v_string = NULL; // don't free it now | |
1415 ++count; | |
1416 } | |
1417 clear_tv(&tv); | |
1418 } | |
1419 | |
1420 if (**arg != '{') | |
1421 { | |
1422 // found terminating quote | |
1423 ++*arg; | |
1424 break; | |
1425 } | |
1426 | |
1427 p = compile_one_expr_in_str(*arg, cctx); | |
1428 if (p == NULL) | |
1429 { | |
1430 ret = FAIL; | |
1431 break; | |
1432 } | |
1433 ++count; | |
1434 *arg = p; | |
1435 } | |
1394 | 1436 |
1395 if (ret == FAIL || !evaluate) | 1437 if (ret == FAIL || !evaluate) |
1396 return ret; | 1438 return ret; |
1397 | 1439 |
1398 ret = compile_all_expr_in_str(tv.vval.v_string, TRUE, cctx); | 1440 // Small optimization, if there's only a single piece skip the ISN_CONCAT. |
1399 clear_tv(&tv); | 1441 if (count > 1) |
1400 | 1442 return generate_CONCAT(cctx, count); |
1401 return ret; | 1443 |
1444 return OK; | |
1402 } | 1445 } |
1403 | 1446 |
1404 /* | 1447 /* |
1405 * Compile "@r". | 1448 * Compile "@r". |
1406 */ | 1449 */ |
2159 break; | 2202 break; |
2160 | 2203 |
2161 /* | 2204 /* |
2162 * String constant: "string". | 2205 * String constant: "string". |
2163 */ | 2206 */ |
2164 case '"': if (eval_string(arg, rettv, TRUE) == FAIL) | 2207 case '"': if (eval_string(arg, rettv, TRUE, FALSE) == FAIL) |
2165 return FAIL; | 2208 return FAIL; |
2166 break; | 2209 break; |
2167 | 2210 |
2168 /* | 2211 /* |
2169 * Literal string constant: 'str''ing'. | 2212 * Literal string constant: 'str''ing'. |
2170 */ | 2213 */ |
2171 case '\'': if (eval_lit_string(arg, rettv, TRUE) == FAIL) | 2214 case '\'': if (eval_lit_string(arg, rettv, TRUE, FALSE) == FAIL) |
2172 return FAIL; | 2215 return FAIL; |
2173 break; | 2216 break; |
2174 | 2217 |
2175 /* | 2218 /* |
2176 * Constant Vim variable. | 2219 * Constant Vim variable. |