comparison src/evalvars.c @ 26317:f44ce6a85c34 v8.2.3689

patch 8.2.3689: ex_let_one() is too long Commit: https://github.com/vim/vim/commit/3ccb5795168793e1b119a028da4035f77cef9f69 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Nov 28 19:53:42 2021 +0000 patch 8.2.3689: ex_let_one() is too long Problem: ex_let_one() is too long. Solution: Split into multiple functions.
author Bram Moolenaar <Bram@vim.org>
date Sun, 28 Nov 2021 21:00:03 +0100
parents 7351926fbe9e
children 55e658312376
comparison
equal deleted inserted replaced
26316:c60f51a7a0d3 26317:f44ce6a85c34
1287 1287
1288 return arg; 1288 return arg;
1289 } 1289 }
1290 1290
1291 /* 1291 /*
1292 * Set an environment variable, part of ex_let_one().
1293 */
1294 static char_u *
1295 ex_let_env(
1296 char_u *arg,
1297 typval_T *tv,
1298 int flags,
1299 char_u *endchars,
1300 char_u *op)
1301 {
1302 char_u *arg_end = NULL;
1303 char_u *name;
1304 int len;
1305
1306 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1307 && (flags & ASSIGN_FOR_LOOP) == 0)
1308 {
1309 emsg(_("E996: Cannot lock an environment variable"));
1310 return NULL;
1311 }
1312
1313 // Find the end of the name.
1314 ++arg;
1315 name = arg;
1316 len = get_env_len(&arg);
1317 if (len == 0)
1318 semsg(_(e_invarg2), name - 1);
1319 else
1320 {
1321 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL)
1322 semsg(_(e_letwrong), op);
1323 else if (endchars != NULL
1324 && vim_strchr(endchars, *skipwhite(arg)) == NULL)
1325 emsg(_(e_unexpected_characters_in_let));
1326 else if (!check_secure())
1327 {
1328 char_u *tofree = NULL;
1329 int c1 = name[len];
1330 char_u *p;
1331
1332 name[len] = NUL;
1333 p = tv_get_string_chk(tv);
1334 if (p != NULL && op != NULL && *op == '.')
1335 {
1336 int mustfree = FALSE;
1337 char_u *s = vim_getenv(name, &mustfree);
1338
1339 if (s != NULL)
1340 {
1341 p = tofree = concat_str(s, p);
1342 if (mustfree)
1343 vim_free(s);
1344 }
1345 }
1346 if (p != NULL)
1347 {
1348 vim_setenv_ext(name, p);
1349 arg_end = arg;
1350 }
1351 name[len] = c1;
1352 vim_free(tofree);
1353 }
1354 }
1355 return arg_end;
1356 }
1357
1358 /*
1359 * Set an option, part of ex_let_one().
1360 */
1361 static char_u *
1362 ex_let_option(
1363 char_u *arg,
1364 typval_T *tv,
1365 int flags,
1366 char_u *endchars,
1367 char_u *op)
1368 {
1369 char_u *p;
1370 int opt_flags;
1371 char_u *arg_end = NULL;
1372
1373 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1374 && (flags & ASSIGN_FOR_LOOP) == 0)
1375 {
1376 emsg(_(e_const_option));
1377 return NULL;
1378 }
1379
1380 // Find the end of the name.
1381 p = find_option_end(&arg, &opt_flags);
1382 if (p == NULL || (endchars != NULL
1383 && vim_strchr(endchars, *skipwhite(p)) == NULL))
1384 emsg(_(e_unexpected_characters_in_let));
1385 else
1386 {
1387 int c1;
1388 long n = 0;
1389 getoption_T opt_type;
1390 long numval;
1391 char_u *stringval = NULL;
1392 char_u *s = NULL;
1393 int failed = FALSE;
1394
1395 c1 = *p;
1396 *p = NUL;
1397
1398 opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
1399 if ((opt_type == gov_bool
1400 || opt_type == gov_number
1401 || opt_type == gov_hidden_bool
1402 || opt_type == gov_hidden_number)
1403 && (tv->v_type != VAR_STRING || !in_vim9script()))
1404 {
1405 if (opt_type == gov_bool || opt_type == gov_hidden_bool)
1406 // bool, possibly hidden
1407 n = (long)tv_get_bool(tv);
1408 else
1409 // number, possibly hidden
1410 n = (long)tv_get_number(tv);
1411 }
1412
1413 // Avoid setting a string option to the text "v:false" or similar.
1414 // In Vim9 script also don't convert a number to string.
1415 if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL
1416 && (!in_vim9script() || tv->v_type != VAR_NUMBER))
1417 s = tv_get_string_chk(tv);
1418
1419 if (op != NULL && *op != '=')
1420 {
1421 if (((opt_type == gov_bool || opt_type == gov_number) && *op == '.')
1422 || (opt_type == gov_string && *op != '.'))
1423 {
1424 semsg(_(e_letwrong), op);
1425 failed = TRUE; // don't set the value
1426
1427 }
1428 else
1429 {
1430 // number, in legacy script also bool
1431 if (opt_type == gov_number
1432 || (opt_type == gov_bool && !in_vim9script()))
1433 {
1434 switch (*op)
1435 {
1436 case '+': n = numval + n; break;
1437 case '-': n = numval - n; break;
1438 case '*': n = numval * n; break;
1439 case '/': n = (long)num_divide(numval, n,
1440 &failed); break;
1441 case '%': n = (long)num_modulus(numval, n,
1442 &failed); break;
1443 }
1444 s = NULL;
1445 }
1446 else if (opt_type == gov_string
1447 && stringval != NULL && s != NULL)
1448 {
1449 // string
1450 s = concat_str(stringval, s);
1451 vim_free(stringval);
1452 stringval = s;
1453 }
1454 }
1455 }
1456
1457 if (!failed)
1458 {
1459 if (opt_type != gov_string || s != NULL)
1460 {
1461 set_option_value(arg, n, s, opt_flags);
1462 arg_end = p;
1463 }
1464 else
1465 emsg(_(e_stringreq));
1466 }
1467 *p = c1;
1468 vim_free(stringval);
1469 }
1470 return arg_end;
1471 }
1472
1473 /*
1474 * Set a register, part of ex_let_one().
1475 */
1476 static char_u *
1477 ex_let_register(
1478 char_u *arg,
1479 typval_T *tv,
1480 int flags,
1481 char_u *endchars,
1482 char_u *op)
1483 {
1484 char_u *arg_end = NULL;
1485
1486 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1487 && (flags & ASSIGN_FOR_LOOP) == 0)
1488 {
1489 emsg(_("E996: Cannot lock a register"));
1490 return NULL;
1491 }
1492 ++arg;
1493 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL)
1494 semsg(_(e_letwrong), op);
1495 else if (endchars != NULL
1496 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
1497 emsg(_(e_unexpected_characters_in_let));
1498 else
1499 {
1500 char_u *ptofree = NULL;
1501 char_u *p;
1502
1503 p = tv_get_string_chk(tv);
1504 if (p != NULL && op != NULL && *op == '.')
1505 {
1506 char_u *s = get_reg_contents(*arg == '@'
1507 ? '"' : *arg, GREG_EXPR_SRC);
1508
1509 if (s != NULL)
1510 {
1511 p = ptofree = concat_str(s, p);
1512 vim_free(s);
1513 }
1514 }
1515 if (p != NULL)
1516 {
1517 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
1518 arg_end = arg + 1;
1519 }
1520 vim_free(ptofree);
1521 }
1522 return arg_end;
1523 }
1524
1525 /*
1292 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 1526 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value.
1293 * Returns a pointer to the char just after the var name. 1527 * Returns a pointer to the char just after the var name.
1294 * Returns NULL if there is an error. 1528 * Returns NULL if there is an error.
1295 */ 1529 */
1296 static char_u * 1530 static char_u *
1301 int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc. 1535 int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc.
1302 char_u *endchars, // valid chars after variable name or NULL 1536 char_u *endchars, // valid chars after variable name or NULL
1303 char_u *op, // "+", "-", "." or NULL 1537 char_u *op, // "+", "-", "." or NULL
1304 int var_idx) // variable index for "let [a, b] = list" 1538 int var_idx) // variable index for "let [a, b] = list"
1305 { 1539 {
1306 int c1;
1307 char_u *name;
1308 char_u *p;
1309 char_u *arg_end = NULL; 1540 char_u *arg_end = NULL;
1310 int len;
1311 int opt_flags;
1312 char_u *tofree = NULL;
1313 1541
1314 if (in_vim9script() && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0 1542 if (in_vim9script() && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
1315 && (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0 1543 && (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
1316 && vim_strchr((char_u *)"$@&", *arg) != NULL) 1544 && vim_strchr((char_u *)"$@&", *arg) != NULL)
1317 { 1545 {
1318 vim9_declare_error(arg); 1546 vim9_declare_error(arg);
1319 return NULL; 1547 return NULL;
1320 } 1548 }
1321 1549
1322 // ":let $VAR = expr": Set environment variable.
1323 if (*arg == '$') 1550 if (*arg == '$')
1324 { 1551 {
1325 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1552 // ":let $VAR = expr": Set environment variable.
1326 && (flags & ASSIGN_FOR_LOOP) == 0) 1553 return ex_let_env(arg, tv, flags, endchars, op);
1327 { 1554 }
1328 emsg(_("E996: Cannot lock an environment variable"));
1329 return NULL;
1330 }
1331
1332 // Find the end of the name.
1333 ++arg;
1334 name = arg;
1335 len = get_env_len(&arg);
1336 if (len == 0)
1337 semsg(_(e_invarg2), name - 1);
1338 else
1339 {
1340 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL)
1341 semsg(_(e_letwrong), op);
1342 else if (endchars != NULL
1343 && vim_strchr(endchars, *skipwhite(arg)) == NULL)
1344 emsg(_(e_unexpected_characters_in_let));
1345 else if (!check_secure())
1346 {
1347 c1 = name[len];
1348 name[len] = NUL;
1349 p = tv_get_string_chk(tv);
1350 if (p != NULL && op != NULL && *op == '.')
1351 {
1352 int mustfree = FALSE;
1353 char_u *s = vim_getenv(name, &mustfree);
1354
1355 if (s != NULL)
1356 {
1357 p = tofree = concat_str(s, p);
1358 if (mustfree)
1359 vim_free(s);
1360 }
1361 }
1362 if (p != NULL)
1363 {
1364 vim_setenv_ext(name, p);
1365 arg_end = arg;
1366 }
1367 name[len] = c1;
1368 vim_free(tofree);
1369 }
1370 }
1371 }
1372
1373 // ":let &option = expr": Set option value.
1374 // ":let &l:option = expr": Set local option value.
1375 // ":let &g:option = expr": Set global option value.
1376 // ":for &ts in range(8)": Set option value for for loop
1377 else if (*arg == '&') 1555 else if (*arg == '&')
1378 { 1556 {
1379 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1557 // ":let &option = expr": Set option value.
1380 && (flags & ASSIGN_FOR_LOOP) == 0) 1558 // ":let &l:option = expr": Set local option value.
1381 { 1559 // ":let &g:option = expr": Set global option value.
1382 emsg(_(e_const_option)); 1560 // ":for &ts in range(8)": Set option value for for loop
1383 return NULL; 1561 return ex_let_option(arg, tv, flags, endchars, op);
1384 } 1562 }
1385 // Find the end of the name.
1386 p = find_option_end(&arg, &opt_flags);
1387 if (p == NULL || (endchars != NULL
1388 && vim_strchr(endchars, *skipwhite(p)) == NULL))
1389 emsg(_(e_unexpected_characters_in_let));
1390 else
1391 {
1392 long n = 0;
1393 getoption_T opt_type;
1394 long numval;
1395 char_u *stringval = NULL;
1396 char_u *s = NULL;
1397 int failed = FALSE;
1398
1399 c1 = *p;
1400 *p = NUL;
1401
1402 opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
1403 if ((opt_type == gov_bool
1404 || opt_type == gov_number
1405 || opt_type == gov_hidden_bool
1406 || opt_type == gov_hidden_number)
1407 && (tv->v_type != VAR_STRING || !in_vim9script()))
1408 {
1409 if (opt_type == gov_bool || opt_type == gov_hidden_bool)
1410 // bool, possibly hidden
1411 n = (long)tv_get_bool(tv);
1412 else
1413 // number, possibly hidden
1414 n = (long)tv_get_number(tv);
1415 }
1416
1417 // Avoid setting a string option to the text "v:false" or similar.
1418 // In Vim9 script also don't convert a number to string.
1419 if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL
1420 && (!in_vim9script() || tv->v_type != VAR_NUMBER))
1421 s = tv_get_string_chk(tv);
1422
1423 if (op != NULL && *op != '=')
1424 {
1425 if (((opt_type == gov_bool || opt_type == gov_number)
1426 && *op == '.')
1427 || (opt_type == gov_string && *op != '.'))
1428 {
1429 semsg(_(e_letwrong), op);
1430 failed = TRUE; // don't set the value
1431
1432 }
1433 else
1434 {
1435 // number, in legacy script also bool
1436 if (opt_type == gov_number
1437 || (opt_type == gov_bool && !in_vim9script()))
1438 {
1439 switch (*op)
1440 {
1441 case '+': n = numval + n; break;
1442 case '-': n = numval - n; break;
1443 case '*': n = numval * n; break;
1444 case '/': n = (long)num_divide(numval, n,
1445 &failed); break;
1446 case '%': n = (long)num_modulus(numval, n,
1447 &failed); break;
1448 }
1449 s = NULL;
1450 }
1451 else if (opt_type == gov_string
1452 && stringval != NULL && s != NULL)
1453 {
1454 // string
1455 s = concat_str(stringval, s);
1456 vim_free(stringval);
1457 stringval = s;
1458 }
1459 }
1460 }
1461
1462 if (!failed)
1463 {
1464 if (opt_type != gov_string || s != NULL)
1465 {
1466 set_option_value(arg, n, s, opt_flags);
1467 arg_end = p;
1468 }
1469 else
1470 emsg(_(e_stringreq));
1471 }
1472 *p = c1;
1473 vim_free(stringval);
1474 }
1475 }
1476
1477 // ":let @r = expr": Set register contents.
1478 else if (*arg == '@') 1563 else if (*arg == '@')
1479 { 1564 {
1480 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1565 // ":let @r = expr": Set register contents.
1481 && (flags & ASSIGN_FOR_LOOP) == 0) 1566 return ex_let_register(arg, tv, flags, endchars, op);
1482 { 1567 }
1483 emsg(_("E996: Cannot lock a register"));
1484 return NULL;
1485 }
1486 ++arg;
1487 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL)
1488 semsg(_(e_letwrong), op);
1489 else if (endchars != NULL
1490 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
1491 emsg(_(e_unexpected_characters_in_let));
1492 else
1493 {
1494 char_u *ptofree = NULL;
1495 char_u *s;
1496
1497 p = tv_get_string_chk(tv);
1498 if (p != NULL && op != NULL && *op == '.')
1499 {
1500 s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC);
1501 if (s != NULL)
1502 {
1503 p = ptofree = concat_str(s, p);
1504 vim_free(s);
1505 }
1506 }
1507 if (p != NULL)
1508 {
1509 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
1510 arg_end = arg + 1;
1511 }
1512 vim_free(ptofree);
1513 }
1514 }
1515
1516 // ":let var = expr": Set internal variable.
1517 // ":let var: type = expr": Set internal variable with type.
1518 // ":let {expr} = expr": Idem, name made with curly braces
1519 else if (eval_isnamec1(*arg) || *arg == '{') 1568 else if (eval_isnamec1(*arg) || *arg == '{')
1520 { 1569 {
1521 lval_T lv; 1570 lval_T lv;
1522 1571 char_u *p;
1572
1573 // ":let var = expr": Set internal variable.
1574 // ":let var: type = expr": Set internal variable with type.
1575 // ":let {expr} = expr": Idem, name made with curly braces
1523 p = get_lval(arg, tv, &lv, FALSE, FALSE, 1576 p = get_lval(arg, tv, &lv, FALSE, FALSE,
1524 (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) 1577 (flags & (ASSIGN_NO_DECL | ASSIGN_DECL))
1525 ? GLV_NO_DECL : 0, FNE_CHECK_START); 1578 ? GLV_NO_DECL : 0, FNE_CHECK_START);
1526 if (p != NULL && lv.ll_name != NULL) 1579 if (p != NULL && lv.ll_name != NULL)
1527 { 1580 {
1528 if (endchars != NULL && vim_strchr(endchars, 1581 if (endchars != NULL && vim_strchr(endchars,
1529 *skipwhite(lv.ll_name_end)) == NULL) 1582 *skipwhite(lv.ll_name_end)) == NULL)
1583 {
1530 emsg(_(e_unexpected_characters_in_let)); 1584 emsg(_(e_unexpected_characters_in_let));
1585 }
1531 else 1586 else
1532 { 1587 {
1533 set_var_lval(&lv, p, tv, copy, flags, op, var_idx); 1588 set_var_lval(&lv, p, tv, copy, flags, op, var_idx);
1534 arg_end = lv.ll_name_end; 1589 arg_end = lv.ll_name_end;
1535 } 1590 }
1536 } 1591 }
1537 clear_lval(&lv); 1592 clear_lval(&lv);
1538 } 1593 }
1539
1540 else 1594 else
1541 semsg(_(e_invarg2), arg); 1595 semsg(_(e_invarg2), arg);
1542 1596
1543 return arg_end; 1597 return arg_end;
1544 } 1598 }