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.