Mercurial > vim
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 } |