Mercurial > vim
comparison src/eval.c @ 17873:d50a5faa75bd v8.1.1933
patch 8.1.1933: the eval.c file is too big
Commit: https://github.com/vim/vim/commit/0522ba0359c96a8c2a4fc8fca0d3b58e49dda759
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Aug 27 22:48:30 2019 +0200
patch 8.1.1933: the eval.c file is too big
Problem: The eval.c file is too big.
Solution: Move code related to variables to evalvars.c. (Yegappan
Lakshmanan, closes #4868)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 27 Aug 2019 23:00:04 +0200 |
parents | 8377ec7c5824 |
children | 5e2d8840da11 |
comparison
equal
deleted
inserted
replaced
17872:a4a0f826d4d7 | 17873:d50a5faa75bd |
---|---|
18 | 18 |
19 #ifdef VMS | 19 #ifdef VMS |
20 # include <float.h> | 20 # include <float.h> |
21 #endif | 21 #endif |
22 | 22 |
23 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ | |
24 | |
25 static char *e_letunexp = N_("E18: Unexpected characters in :let"); | |
26 static char *e_undefvar = N_("E121: Undefined variable: %s"); | |
27 static char *e_missbrac = N_("E111: Missing ']'"); | 23 static char *e_missbrac = N_("E111: Missing ']'"); |
28 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); | 24 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); |
29 static char *e_letwrong = N_("E734: Wrong variable type for %s="); | |
30 static char *e_illvar = N_("E461: Illegal variable name: %s"); | |
31 static char *e_cannot_mod = N_("E995: Cannot modify existing variable"); | |
32 #ifdef FEAT_FLOAT | 25 #ifdef FEAT_FLOAT |
33 static char *e_float_as_string = N_("E806: using Float as a String"); | 26 static char *e_float_as_string = N_("E806: using Float as a String"); |
34 #endif | 27 #endif |
35 static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); | 28 static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); |
36 | 29 |
215 #define vv_tv vv_di.di_tv | 208 #define vv_tv vv_di.di_tv |
216 | 209 |
217 static dictitem_T vimvars_var; /* variable used for v: */ | 210 static dictitem_T vimvars_var; /* variable used for v: */ |
218 #define vimvarht vimvardict.dv_hashtab | 211 #define vimvarht vimvardict.dv_hashtab |
219 | 212 |
220 static void ex_let_const(exarg_T *eap, int is_const); | |
221 static int ex_let_vars(char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, int is_const, char_u *nextchars); | |
222 static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon); | |
223 static char_u *skip_var_one(char_u *arg); | |
224 static void list_glob_vars(int *first); | |
225 static void list_buf_vars(int *first); | |
226 static void list_win_vars(int *first); | |
227 static void list_tab_vars(int *first); | |
228 static void list_vim_vars(int *first); | |
229 static void list_script_vars(int *first); | |
230 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); | |
231 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int is_const, char_u *endchars, char_u *op); | |
232 static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, int is_const, char_u *op); | |
233 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); | 213 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); |
234 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); | |
235 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); | |
236 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); | |
237 static void item_lock(typval_T *tv, int deep, int lock); | |
238 | |
239 static int eval2(char_u **arg, typval_T *rettv, int evaluate); | 214 static int eval2(char_u **arg, typval_T *rettv, int evaluate); |
240 static int eval3(char_u **arg, typval_T *rettv, int evaluate); | 215 static int eval3(char_u **arg, typval_T *rettv, int evaluate); |
241 static int eval4(char_u **arg, typval_T *rettv, int evaluate); | 216 static int eval4(char_u **arg, typval_T *rettv, int evaluate); |
242 static int eval5(char_u **arg, typval_T *rettv, int evaluate); | 217 static int eval5(char_u **arg, typval_T *rettv, int evaluate); |
243 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); | 218 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); |
246 | 221 |
247 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); | 222 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); |
248 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); | 223 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); |
249 static int free_unref_items(int copyID); | 224 static int free_unref_items(int copyID); |
250 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); | 225 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); |
251 static int get_env_len(char_u **arg); | |
252 static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose); | |
253 static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); | 226 static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); |
254 static int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload); | |
255 static void check_vars(char_u *name, int len); | 227 static void check_vars(char_u *name, int len); |
256 static typval_T *alloc_string_tv(char_u *string); | 228 static typval_T *alloc_string_tv(char_u *string); |
257 static void delete_var(hashtab_T *ht, hashitem_T *hi); | |
258 static void list_one_var(dictitem_T *v, char *prefix, int *first); | |
259 static void list_one_var_a(char *prefix, char_u *name, int type, char_u *string, int *first); | |
260 static void set_var_const(char_u *name, typval_T *tv, int copy, int is_const); | |
261 static int tv_check_lock(typval_T *tv, char_u *name, int use_gettext); | 229 static int tv_check_lock(typval_T *tv, char_u *name, int use_gettext); |
262 static char_u *find_option_end(char_u **arg, int *opt_flags); | |
263 | 230 |
264 /* for VIM_VERSION_ defines */ | 231 /* for VIM_VERSION_ defines */ |
265 #include "version.h" | 232 #include "version.h" |
266 | 233 |
267 /* | 234 /* |
268 * Return "n1" divided by "n2", taking care of dividing by zero. | 235 * Return "n1" divided by "n2", taking care of dividing by zero. |
269 */ | 236 */ |
270 static varnumber_T | 237 varnumber_T |
271 num_divide(varnumber_T n1, varnumber_T n2) | 238 num_divide(varnumber_T n1, varnumber_T n2) |
272 { | 239 { |
273 varnumber_T result; | 240 varnumber_T result; |
274 | 241 |
275 if (n2 == 0) // give an error message? | 242 if (n2 == 0) // give an error message? |
288 } | 255 } |
289 | 256 |
290 /* | 257 /* |
291 * Return "n1" modulus "n2", taking care of dividing by zero. | 258 * Return "n1" modulus "n2", taking care of dividing by zero. |
292 */ | 259 */ |
293 static varnumber_T | 260 varnumber_T |
294 num_modulus(varnumber_T n1, varnumber_T n2) | 261 num_modulus(varnumber_T n1, varnumber_T n2) |
295 { | 262 { |
296 // Give an error when n2 is 0? | 263 // Give an error when n2 is 0? |
297 return (n2 == 0) ? 0 : (n1 % n2); | 264 return (n2 == 0) ? 0 : (n1 % n2); |
298 } | 265 } |
976 | 943 |
977 return retval; | 944 return retval; |
978 } | 945 } |
979 | 946 |
980 /* | 947 /* |
948 * List Vim variables. | |
949 */ | |
950 void | |
951 list_vim_vars(int *first) | |
952 { | |
953 list_hashtable_vars(&vimvarht, "v:", FALSE, first); | |
954 } | |
955 | |
956 /* | |
957 * List script-local variables, if there is a script. | |
958 */ | |
959 void | |
960 list_script_vars(int *first) | |
961 { | |
962 if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len) | |
963 list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), | |
964 "s:", FALSE, first); | |
965 } | |
966 | |
967 int | |
968 is_vimvarht(hashtab_T *ht) | |
969 { | |
970 return ht == &vimvarht; | |
971 } | |
972 | |
973 int | |
974 is_compatht(hashtab_T *ht) | |
975 { | |
976 return ht == &compat_hashtab; | |
977 } | |
978 | |
979 /* | |
981 * Prepare v: variable "idx" to be used. | 980 * Prepare v: variable "idx" to be used. |
982 * Save the current typeval in "save_tv". | 981 * Save the current typeval in "save_tv". |
983 * When not used yet add the variable to the v: hashtable. | 982 * When not used yet add the variable to the v: hashtable. |
984 */ | 983 */ |
985 void | 984 void |
1233 --textlock; | 1232 --textlock; |
1234 | 1233 |
1235 return (int)retval; | 1234 return (int)retval; |
1236 } | 1235 } |
1237 #endif | 1236 #endif |
1238 | |
1239 /* | |
1240 * Get a list of lines from a HERE document. The here document is a list of | |
1241 * lines surrounded by a marker. | |
1242 * cmd << {marker} | |
1243 * {line1} | |
1244 * {line2} | |
1245 * .... | |
1246 * {marker} | |
1247 * | |
1248 * The {marker} is a string. If the optional 'trim' word is supplied before the | |
1249 * marker, then the leading indentation before the lines (matching the | |
1250 * indentation in the 'cmd' line) is stripped. | |
1251 * Returns a List with {lines} or NULL. | |
1252 */ | |
1253 static list_T * | |
1254 heredoc_get(exarg_T *eap, char_u *cmd) | |
1255 { | |
1256 char_u *theline; | |
1257 char_u *marker; | |
1258 list_T *l; | |
1259 char_u *p; | |
1260 int marker_indent_len = 0; | |
1261 int text_indent_len = 0; | |
1262 char_u *text_indent = NULL; | |
1263 | |
1264 if (eap->getline == NULL) | |
1265 { | |
1266 emsg(_("E991: cannot use =<< here")); | |
1267 return NULL; | |
1268 } | |
1269 | |
1270 // Check for the optional 'trim' word before the marker | |
1271 cmd = skipwhite(cmd); | |
1272 if (STRNCMP(cmd, "trim", 4) == 0 && (cmd[4] == NUL || VIM_ISWHITE(cmd[4]))) | |
1273 { | |
1274 cmd = skipwhite(cmd + 4); | |
1275 | |
1276 // Trim the indentation from all the lines in the here document. | |
1277 // The amount of indentation trimmed is the same as the indentation of | |
1278 // the first line after the :let command line. To find the end marker | |
1279 // the indent of the :let command line is trimmed. | |
1280 p = *eap->cmdlinep; | |
1281 while (VIM_ISWHITE(*p)) | |
1282 { | |
1283 p++; | |
1284 marker_indent_len++; | |
1285 } | |
1286 text_indent_len = -1; | |
1287 } | |
1288 | |
1289 // The marker is the next word. | |
1290 if (*cmd != NUL && *cmd != '"') | |
1291 { | |
1292 marker = skipwhite(cmd); | |
1293 p = skiptowhite(marker); | |
1294 if (*skipwhite(p) != NUL && *skipwhite(p) != '"') | |
1295 { | |
1296 emsg(_(e_trailing)); | |
1297 return NULL; | |
1298 } | |
1299 *p = NUL; | |
1300 if (vim_islower(*marker)) | |
1301 { | |
1302 emsg(_("E221: Marker cannot start with lower case letter")); | |
1303 return NULL; | |
1304 } | |
1305 } | |
1306 else | |
1307 { | |
1308 emsg(_("E172: Missing marker")); | |
1309 return NULL; | |
1310 } | |
1311 | |
1312 l = list_alloc(); | |
1313 if (l == NULL) | |
1314 return NULL; | |
1315 | |
1316 for (;;) | |
1317 { | |
1318 int mi = 0; | |
1319 int ti = 0; | |
1320 | |
1321 theline = eap->getline(NUL, eap->cookie, 0, FALSE); | |
1322 if (theline == NULL) | |
1323 { | |
1324 semsg(_("E990: Missing end marker '%s'"), marker); | |
1325 break; | |
1326 } | |
1327 | |
1328 // with "trim": skip the indent matching the :let line to find the | |
1329 // marker | |
1330 if (marker_indent_len > 0 | |
1331 && STRNCMP(theline, *eap->cmdlinep, marker_indent_len) == 0) | |
1332 mi = marker_indent_len; | |
1333 if (STRCMP(marker, theline + mi) == 0) | |
1334 { | |
1335 vim_free(theline); | |
1336 break; | |
1337 } | |
1338 | |
1339 if (text_indent_len == -1 && *theline != NUL) | |
1340 { | |
1341 // set the text indent from the first line. | |
1342 p = theline; | |
1343 text_indent_len = 0; | |
1344 while (VIM_ISWHITE(*p)) | |
1345 { | |
1346 p++; | |
1347 text_indent_len++; | |
1348 } | |
1349 text_indent = vim_strnsave(theline, text_indent_len); | |
1350 } | |
1351 // with "trim": skip the indent matching the first line | |
1352 if (text_indent != NULL) | |
1353 for (ti = 0; ti < text_indent_len; ++ti) | |
1354 if (theline[ti] != text_indent[ti]) | |
1355 break; | |
1356 | |
1357 if (list_append_string(l, theline + ti, -1) == FAIL) | |
1358 break; | |
1359 vim_free(theline); | |
1360 } | |
1361 vim_free(text_indent); | |
1362 | |
1363 return l; | |
1364 } | |
1365 | |
1366 /* | |
1367 * ":let" list all variable values | |
1368 * ":let var1 var2" list variable values | |
1369 * ":let var = expr" assignment command. | |
1370 * ":let var += expr" assignment command. | |
1371 * ":let var -= expr" assignment command. | |
1372 * ":let var *= expr" assignment command. | |
1373 * ":let var /= expr" assignment command. | |
1374 * ":let var %= expr" assignment command. | |
1375 * ":let var .= expr" assignment command. | |
1376 * ":let var ..= expr" assignment command. | |
1377 * ":let [var1, var2] = expr" unpack list. | |
1378 */ | |
1379 void | |
1380 ex_let(exarg_T *eap) | |
1381 { | |
1382 ex_let_const(eap, FALSE); | |
1383 } | |
1384 | |
1385 /* | |
1386 * ":const" list all variable values | |
1387 * ":const var1 var2" list variable values | |
1388 * ":const var = expr" assignment command. | |
1389 * ":const [var1, var2] = expr" unpack list. | |
1390 */ | |
1391 void | |
1392 ex_const(exarg_T *eap) | |
1393 { | |
1394 ex_let_const(eap, TRUE); | |
1395 } | |
1396 | |
1397 static void | |
1398 ex_let_const(exarg_T *eap, int is_const) | |
1399 { | |
1400 char_u *arg = eap->arg; | |
1401 char_u *expr = NULL; | |
1402 typval_T rettv; | |
1403 int i; | |
1404 int var_count = 0; | |
1405 int semicolon = 0; | |
1406 char_u op[2]; | |
1407 char_u *argend; | |
1408 int first = TRUE; | |
1409 int concat; | |
1410 | |
1411 argend = skip_var_list(arg, &var_count, &semicolon); | |
1412 if (argend == NULL) | |
1413 return; | |
1414 if (argend > arg && argend[-1] == '.') // for var.='str' | |
1415 --argend; | |
1416 expr = skipwhite(argend); | |
1417 concat = expr[0] == '.' | |
1418 && ((expr[1] == '=' && current_sctx.sc_version < 2) | |
1419 || (expr[1] == '.' && expr[2] == '=')); | |
1420 if (*expr != '=' && !((vim_strchr((char_u *)"+-*/%", *expr) != NULL | |
1421 && expr[1] == '=') || concat)) | |
1422 { | |
1423 /* | |
1424 * ":let" without "=": list variables | |
1425 */ | |
1426 if (*arg == '[') | |
1427 emsg(_(e_invarg)); | |
1428 else if (expr[0] == '.') | |
1429 emsg(_("E985: .= is not supported with script version 2")); | |
1430 else if (!ends_excmd(*arg)) | |
1431 /* ":let var1 var2" */ | |
1432 arg = list_arg_vars(eap, arg, &first); | |
1433 else if (!eap->skip) | |
1434 { | |
1435 /* ":let" */ | |
1436 list_glob_vars(&first); | |
1437 list_buf_vars(&first); | |
1438 list_win_vars(&first); | |
1439 list_tab_vars(&first); | |
1440 list_script_vars(&first); | |
1441 list_func_vars(&first); | |
1442 list_vim_vars(&first); | |
1443 } | |
1444 eap->nextcmd = check_nextcmd(arg); | |
1445 } | |
1446 else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<') | |
1447 { | |
1448 list_T *l; | |
1449 | |
1450 // HERE document | |
1451 l = heredoc_get(eap, expr + 3); | |
1452 if (l != NULL) | |
1453 { | |
1454 rettv_list_set(&rettv, l); | |
1455 op[0] = '='; | |
1456 op[1] = NUL; | |
1457 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, | |
1458 is_const, op); | |
1459 clear_tv(&rettv); | |
1460 } | |
1461 } | |
1462 else | |
1463 { | |
1464 op[0] = '='; | |
1465 op[1] = NUL; | |
1466 if (*expr != '=') | |
1467 { | |
1468 if (vim_strchr((char_u *)"+-*/%.", *expr) != NULL) | |
1469 { | |
1470 op[0] = *expr; // +=, -=, *=, /=, %= or .= | |
1471 if (expr[0] == '.' && expr[1] == '.') // ..= | |
1472 ++expr; | |
1473 } | |
1474 expr = skipwhite(expr + 2); | |
1475 } | |
1476 else | |
1477 expr = skipwhite(expr + 1); | |
1478 | |
1479 if (eap->skip) | |
1480 ++emsg_skip; | |
1481 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); | |
1482 if (eap->skip) | |
1483 { | |
1484 if (i != FAIL) | |
1485 clear_tv(&rettv); | |
1486 --emsg_skip; | |
1487 } | |
1488 else if (i != FAIL) | |
1489 { | |
1490 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, | |
1491 is_const, op); | |
1492 clear_tv(&rettv); | |
1493 } | |
1494 } | |
1495 } | |
1496 | |
1497 /* | |
1498 * Assign the typevalue "tv" to the variable or variables at "arg_start". | |
1499 * Handles both "var" with any type and "[var, var; var]" with a list type. | |
1500 * When "op" is not NULL it points to a string with characters that | |
1501 * must appear after the variable(s). Use "+", "-" or "." for add, subtract | |
1502 * or concatenate. | |
1503 * Returns OK or FAIL; | |
1504 */ | |
1505 static int | |
1506 ex_let_vars( | |
1507 char_u *arg_start, | |
1508 typval_T *tv, | |
1509 int copy, // copy values from "tv", don't move | |
1510 int semicolon, // from skip_var_list() | |
1511 int var_count, // from skip_var_list() | |
1512 int is_const, // lock variables for const | |
1513 char_u *op) | |
1514 { | |
1515 char_u *arg = arg_start; | |
1516 list_T *l; | |
1517 int i; | |
1518 listitem_T *item; | |
1519 typval_T ltv; | |
1520 | |
1521 if (*arg != '[') | |
1522 { | |
1523 /* | |
1524 * ":let var = expr" or ":for var in list" | |
1525 */ | |
1526 if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) | |
1527 return FAIL; | |
1528 return OK; | |
1529 } | |
1530 | |
1531 /* | |
1532 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" | |
1533 */ | |
1534 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) | |
1535 { | |
1536 emsg(_(e_listreq)); | |
1537 return FAIL; | |
1538 } | |
1539 | |
1540 i = list_len(l); | |
1541 if (semicolon == 0 && var_count < i) | |
1542 { | |
1543 emsg(_("E687: Less targets than List items")); | |
1544 return FAIL; | |
1545 } | |
1546 if (var_count - semicolon > i) | |
1547 { | |
1548 emsg(_("E688: More targets than List items")); | |
1549 return FAIL; | |
1550 } | |
1551 | |
1552 item = l->lv_first; | |
1553 while (*arg != ']') | |
1554 { | |
1555 arg = skipwhite(arg + 1); | |
1556 arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, | |
1557 (char_u *)",;]", op); | |
1558 item = item->li_next; | |
1559 if (arg == NULL) | |
1560 return FAIL; | |
1561 | |
1562 arg = skipwhite(arg); | |
1563 if (*arg == ';') | |
1564 { | |
1565 /* Put the rest of the list (may be empty) in the var after ';'. | |
1566 * Create a new list for this. */ | |
1567 l = list_alloc(); | |
1568 if (l == NULL) | |
1569 return FAIL; | |
1570 while (item != NULL) | |
1571 { | |
1572 list_append_tv(l, &item->li_tv); | |
1573 item = item->li_next; | |
1574 } | |
1575 | |
1576 ltv.v_type = VAR_LIST; | |
1577 ltv.v_lock = 0; | |
1578 ltv.vval.v_list = l; | |
1579 l->lv_refcount = 1; | |
1580 | |
1581 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, | |
1582 (char_u *)"]", op); | |
1583 clear_tv(<v); | |
1584 if (arg == NULL) | |
1585 return FAIL; | |
1586 break; | |
1587 } | |
1588 else if (*arg != ',' && *arg != ']') | |
1589 { | |
1590 internal_error("ex_let_vars()"); | |
1591 return FAIL; | |
1592 } | |
1593 } | |
1594 | |
1595 return OK; | |
1596 } | |
1597 | |
1598 /* | |
1599 * Skip over assignable variable "var" or list of variables "[var, var]". | |
1600 * Used for ":let varvar = expr" and ":for varvar in expr". | |
1601 * For "[var, var]" increment "*var_count" for each variable. | |
1602 * for "[var, var; var]" set "semicolon". | |
1603 * Return NULL for an error. | |
1604 */ | |
1605 static char_u * | |
1606 skip_var_list( | |
1607 char_u *arg, | |
1608 int *var_count, | |
1609 int *semicolon) | |
1610 { | |
1611 char_u *p, *s; | |
1612 | |
1613 if (*arg == '[') | |
1614 { | |
1615 /* "[var, var]": find the matching ']'. */ | |
1616 p = arg; | |
1617 for (;;) | |
1618 { | |
1619 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ | |
1620 s = skip_var_one(p); | |
1621 if (s == p) | |
1622 { | |
1623 semsg(_(e_invarg2), p); | |
1624 return NULL; | |
1625 } | |
1626 ++*var_count; | |
1627 | |
1628 p = skipwhite(s); | |
1629 if (*p == ']') | |
1630 break; | |
1631 else if (*p == ';') | |
1632 { | |
1633 if (*semicolon == 1) | |
1634 { | |
1635 emsg(_("Double ; in list of variables")); | |
1636 return NULL; | |
1637 } | |
1638 *semicolon = 1; | |
1639 } | |
1640 else if (*p != ',') | |
1641 { | |
1642 semsg(_(e_invarg2), p); | |
1643 return NULL; | |
1644 } | |
1645 } | |
1646 return p + 1; | |
1647 } | |
1648 else | |
1649 return skip_var_one(arg); | |
1650 } | |
1651 | |
1652 /* | |
1653 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, | |
1654 * l[idx]. | |
1655 */ | |
1656 static char_u * | |
1657 skip_var_one(char_u *arg) | |
1658 { | |
1659 if (*arg == '@' && arg[1] != NUL) | |
1660 return arg + 2; | |
1661 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, | |
1662 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); | |
1663 } | |
1664 | |
1665 /* | |
1666 * List variables for hashtab "ht" with prefix "prefix". | |
1667 * If "empty" is TRUE also list NULL strings as empty strings. | |
1668 */ | |
1669 void | |
1670 list_hashtable_vars( | |
1671 hashtab_T *ht, | |
1672 char *prefix, | |
1673 int empty, | |
1674 int *first) | |
1675 { | |
1676 hashitem_T *hi; | |
1677 dictitem_T *di; | |
1678 int todo; | |
1679 char_u buf[IOSIZE]; | |
1680 | |
1681 todo = (int)ht->ht_used; | |
1682 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) | |
1683 { | |
1684 if (!HASHITEM_EMPTY(hi)) | |
1685 { | |
1686 --todo; | |
1687 di = HI2DI(hi); | |
1688 | |
1689 // apply :filter /pat/ to variable name | |
1690 vim_strncpy((char_u *)buf, (char_u *)prefix, IOSIZE - 1); | |
1691 vim_strcat((char_u *)buf, di->di_key, IOSIZE); | |
1692 if (message_filtered(buf)) | |
1693 continue; | |
1694 | |
1695 if (empty || di->di_tv.v_type != VAR_STRING | |
1696 || di->di_tv.vval.v_string != NULL) | |
1697 list_one_var(di, prefix, first); | |
1698 } | |
1699 } | |
1700 } | |
1701 | |
1702 /* | |
1703 * List global variables. | |
1704 */ | |
1705 static void | |
1706 list_glob_vars(int *first) | |
1707 { | |
1708 list_hashtable_vars(&globvarht, "", TRUE, first); | |
1709 } | |
1710 | |
1711 /* | |
1712 * List buffer variables. | |
1713 */ | |
1714 static void | |
1715 list_buf_vars(int *first) | |
1716 { | |
1717 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, "b:", TRUE, first); | |
1718 } | |
1719 | |
1720 /* | |
1721 * List window variables. | |
1722 */ | |
1723 static void | |
1724 list_win_vars(int *first) | |
1725 { | |
1726 list_hashtable_vars(&curwin->w_vars->dv_hashtab, "w:", TRUE, first); | |
1727 } | |
1728 | |
1729 /* | |
1730 * List tab page variables. | |
1731 */ | |
1732 static void | |
1733 list_tab_vars(int *first) | |
1734 { | |
1735 list_hashtable_vars(&curtab->tp_vars->dv_hashtab, "t:", TRUE, first); | |
1736 } | |
1737 | |
1738 /* | |
1739 * List Vim variables. | |
1740 */ | |
1741 static void | |
1742 list_vim_vars(int *first) | |
1743 { | |
1744 list_hashtable_vars(&vimvarht, "v:", FALSE, first); | |
1745 } | |
1746 | |
1747 /* | |
1748 * List script-local variables, if there is a script. | |
1749 */ | |
1750 static void | |
1751 list_script_vars(int *first) | |
1752 { | |
1753 if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len) | |
1754 list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), | |
1755 "s:", FALSE, first); | |
1756 } | |
1757 | |
1758 /* | |
1759 * List variables in "arg". | |
1760 */ | |
1761 static char_u * | |
1762 list_arg_vars(exarg_T *eap, char_u *arg, int *first) | |
1763 { | |
1764 int error = FALSE; | |
1765 int len; | |
1766 char_u *name; | |
1767 char_u *name_start; | |
1768 char_u *arg_subsc; | |
1769 char_u *tofree; | |
1770 typval_T tv; | |
1771 | |
1772 while (!ends_excmd(*arg) && !got_int) | |
1773 { | |
1774 if (error || eap->skip) | |
1775 { | |
1776 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); | |
1777 if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg)) | |
1778 { | |
1779 emsg_severe = TRUE; | |
1780 emsg(_(e_trailing)); | |
1781 break; | |
1782 } | |
1783 } | |
1784 else | |
1785 { | |
1786 /* get_name_len() takes care of expanding curly braces */ | |
1787 name_start = name = arg; | |
1788 len = get_name_len(&arg, &tofree, TRUE, TRUE); | |
1789 if (len <= 0) | |
1790 { | |
1791 /* This is mainly to keep test 49 working: when expanding | |
1792 * curly braces fails overrule the exception error message. */ | |
1793 if (len < 0 && !aborting()) | |
1794 { | |
1795 emsg_severe = TRUE; | |
1796 semsg(_(e_invarg2), arg); | |
1797 break; | |
1798 } | |
1799 error = TRUE; | |
1800 } | |
1801 else | |
1802 { | |
1803 if (tofree != NULL) | |
1804 name = tofree; | |
1805 if (get_var_tv(name, len, &tv, NULL, TRUE, FALSE) == FAIL) | |
1806 error = TRUE; | |
1807 else | |
1808 { | |
1809 /* handle d.key, l[idx], f(expr) */ | |
1810 arg_subsc = arg; | |
1811 if (handle_subscript(&arg, &tv, TRUE, TRUE, | |
1812 name, &name) == FAIL) | |
1813 error = TRUE; | |
1814 else | |
1815 { | |
1816 if (arg == arg_subsc && len == 2 && name[1] == ':') | |
1817 { | |
1818 switch (*name) | |
1819 { | |
1820 case 'g': list_glob_vars(first); break; | |
1821 case 'b': list_buf_vars(first); break; | |
1822 case 'w': list_win_vars(first); break; | |
1823 case 't': list_tab_vars(first); break; | |
1824 case 'v': list_vim_vars(first); break; | |
1825 case 's': list_script_vars(first); break; | |
1826 case 'l': list_func_vars(first); break; | |
1827 default: | |
1828 semsg(_("E738: Can't list variables for %s"), name); | |
1829 } | |
1830 } | |
1831 else | |
1832 { | |
1833 char_u numbuf[NUMBUFLEN]; | |
1834 char_u *tf; | |
1835 int c; | |
1836 char_u *s; | |
1837 | |
1838 s = echo_string(&tv, &tf, numbuf, 0); | |
1839 c = *arg; | |
1840 *arg = NUL; | |
1841 list_one_var_a("", | |
1842 arg == arg_subsc ? name : name_start, | |
1843 tv.v_type, | |
1844 s == NULL ? (char_u *)"" : s, | |
1845 first); | |
1846 *arg = c; | |
1847 vim_free(tf); | |
1848 } | |
1849 clear_tv(&tv); | |
1850 } | |
1851 } | |
1852 } | |
1853 | |
1854 vim_free(tofree); | |
1855 } | |
1856 | |
1857 arg = skipwhite(arg); | |
1858 } | |
1859 | |
1860 return arg; | |
1861 } | |
1862 | |
1863 /* | |
1864 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. | |
1865 * Returns a pointer to the char just after the var name. | |
1866 * Returns NULL if there is an error. | |
1867 */ | |
1868 static char_u * | |
1869 ex_let_one( | |
1870 char_u *arg, // points to variable name | |
1871 typval_T *tv, // value to assign to variable | |
1872 int copy, // copy value from "tv" | |
1873 int is_const, // lock variable for const | |
1874 char_u *endchars, // valid chars after variable name or NULL | |
1875 char_u *op) // "+", "-", "." or NULL | |
1876 { | |
1877 int c1; | |
1878 char_u *name; | |
1879 char_u *p; | |
1880 char_u *arg_end = NULL; | |
1881 int len; | |
1882 int opt_flags; | |
1883 char_u *tofree = NULL; | |
1884 | |
1885 /* | |
1886 * ":let $VAR = expr": Set environment variable. | |
1887 */ | |
1888 if (*arg == '$') | |
1889 { | |
1890 if (is_const) | |
1891 { | |
1892 emsg(_("E996: Cannot lock an environment variable")); | |
1893 return NULL; | |
1894 } | |
1895 /* Find the end of the name. */ | |
1896 ++arg; | |
1897 name = arg; | |
1898 len = get_env_len(&arg); | |
1899 if (len == 0) | |
1900 semsg(_(e_invarg2), name - 1); | |
1901 else | |
1902 { | |
1903 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL) | |
1904 semsg(_(e_letwrong), op); | |
1905 else if (endchars != NULL | |
1906 && vim_strchr(endchars, *skipwhite(arg)) == NULL) | |
1907 emsg(_(e_letunexp)); | |
1908 else if (!check_secure()) | |
1909 { | |
1910 c1 = name[len]; | |
1911 name[len] = NUL; | |
1912 p = tv_get_string_chk(tv); | |
1913 if (p != NULL && op != NULL && *op == '.') | |
1914 { | |
1915 int mustfree = FALSE; | |
1916 char_u *s = vim_getenv(name, &mustfree); | |
1917 | |
1918 if (s != NULL) | |
1919 { | |
1920 p = tofree = concat_str(s, p); | |
1921 if (mustfree) | |
1922 vim_free(s); | |
1923 } | |
1924 } | |
1925 if (p != NULL) | |
1926 { | |
1927 vim_setenv(name, p); | |
1928 if (STRICMP(name, "HOME") == 0) | |
1929 init_homedir(); | |
1930 else if (didset_vim && STRICMP(name, "VIM") == 0) | |
1931 didset_vim = FALSE; | |
1932 else if (didset_vimruntime | |
1933 && STRICMP(name, "VIMRUNTIME") == 0) | |
1934 didset_vimruntime = FALSE; | |
1935 arg_end = arg; | |
1936 } | |
1937 name[len] = c1; | |
1938 vim_free(tofree); | |
1939 } | |
1940 } | |
1941 } | |
1942 | |
1943 /* | |
1944 * ":let &option = expr": Set option value. | |
1945 * ":let &l:option = expr": Set local option value. | |
1946 * ":let &g:option = expr": Set global option value. | |
1947 */ | |
1948 else if (*arg == '&') | |
1949 { | |
1950 if (is_const) | |
1951 { | |
1952 emsg(_("E996: Cannot lock an option")); | |
1953 return NULL; | |
1954 } | |
1955 /* Find the end of the name. */ | |
1956 p = find_option_end(&arg, &opt_flags); | |
1957 if (p == NULL || (endchars != NULL | |
1958 && vim_strchr(endchars, *skipwhite(p)) == NULL)) | |
1959 emsg(_(e_letunexp)); | |
1960 else | |
1961 { | |
1962 long n; | |
1963 int opt_type; | |
1964 long numval; | |
1965 char_u *stringval = NULL; | |
1966 char_u *s; | |
1967 | |
1968 c1 = *p; | |
1969 *p = NUL; | |
1970 | |
1971 n = (long)tv_get_number(tv); | |
1972 s = tv_get_string_chk(tv); /* != NULL if number or string */ | |
1973 if (s != NULL && op != NULL && *op != '=') | |
1974 { | |
1975 opt_type = get_option_value(arg, &numval, | |
1976 &stringval, opt_flags); | |
1977 if ((opt_type == 1 && *op == '.') | |
1978 || (opt_type == 0 && *op != '.')) | |
1979 { | |
1980 semsg(_(e_letwrong), op); | |
1981 s = NULL; // don't set the value | |
1982 } | |
1983 else | |
1984 { | |
1985 if (opt_type == 1) // number | |
1986 { | |
1987 switch (*op) | |
1988 { | |
1989 case '+': n = numval + n; break; | |
1990 case '-': n = numval - n; break; | |
1991 case '*': n = numval * n; break; | |
1992 case '/': n = (long)num_divide(numval, n); break; | |
1993 case '%': n = (long)num_modulus(numval, n); break; | |
1994 } | |
1995 } | |
1996 else if (opt_type == 0 && stringval != NULL) // string | |
1997 { | |
1998 s = concat_str(stringval, s); | |
1999 vim_free(stringval); | |
2000 stringval = s; | |
2001 } | |
2002 } | |
2003 } | |
2004 if (s != NULL) | |
2005 { | |
2006 set_option_value(arg, n, s, opt_flags); | |
2007 arg_end = p; | |
2008 } | |
2009 *p = c1; | |
2010 vim_free(stringval); | |
2011 } | |
2012 } | |
2013 | |
2014 /* | |
2015 * ":let @r = expr": Set register contents. | |
2016 */ | |
2017 else if (*arg == '@') | |
2018 { | |
2019 if (is_const) | |
2020 { | |
2021 emsg(_("E996: Cannot lock a register")); | |
2022 return NULL; | |
2023 } | |
2024 ++arg; | |
2025 if (op != NULL && vim_strchr((char_u *)"+-*/%", *op) != NULL) | |
2026 semsg(_(e_letwrong), op); | |
2027 else if (endchars != NULL | |
2028 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) | |
2029 emsg(_(e_letunexp)); | |
2030 else | |
2031 { | |
2032 char_u *ptofree = NULL; | |
2033 char_u *s; | |
2034 | |
2035 p = tv_get_string_chk(tv); | |
2036 if (p != NULL && op != NULL && *op == '.') | |
2037 { | |
2038 s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); | |
2039 if (s != NULL) | |
2040 { | |
2041 p = ptofree = concat_str(s, p); | |
2042 vim_free(s); | |
2043 } | |
2044 } | |
2045 if (p != NULL) | |
2046 { | |
2047 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); | |
2048 arg_end = arg + 1; | |
2049 } | |
2050 vim_free(ptofree); | |
2051 } | |
2052 } | |
2053 | |
2054 /* | |
2055 * ":let var = expr": Set internal variable. | |
2056 * ":let {expr} = expr": Idem, name made with curly braces | |
2057 */ | |
2058 else if (eval_isnamec1(*arg) || *arg == '{') | |
2059 { | |
2060 lval_T lv; | |
2061 | |
2062 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); | |
2063 if (p != NULL && lv.ll_name != NULL) | |
2064 { | |
2065 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) | |
2066 emsg(_(e_letunexp)); | |
2067 else | |
2068 { | |
2069 set_var_lval(&lv, p, tv, copy, is_const, op); | |
2070 arg_end = p; | |
2071 } | |
2072 } | |
2073 clear_lval(&lv); | |
2074 } | |
2075 | |
2076 else | |
2077 semsg(_(e_invarg2), arg); | |
2078 | |
2079 return arg_end; | |
2080 } | |
2081 | 1237 |
2082 /* | 1238 /* |
2083 * Get an lval: variable, Dict item or List item that can be assigned a value | 1239 * Get an lval: variable, Dict item or List item that can be assigned a value |
2084 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", | 1240 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", |
2085 * "name.key", "name.key[expr]" etc. | 1241 * "name.key", "name.key[expr]" etc. |
2500 * Set a variable that was parsed by get_lval() to "rettv". | 1656 * Set a variable that was parsed by get_lval() to "rettv". |
2501 * "endp" points to just after the parsed name. | 1657 * "endp" points to just after the parsed name. |
2502 * "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=", | 1658 * "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=", |
2503 * "%" for "%=", "." for ".=" or "=" for "=". | 1659 * "%" for "%=", "." for ".=" or "=" for "=". |
2504 */ | 1660 */ |
2505 static void | 1661 void |
2506 set_var_lval( | 1662 set_var_lval( |
2507 lval_T *lp, | 1663 lval_T *lp, |
2508 char_u *endp, | 1664 char_u *endp, |
2509 typval_T *rettv, | 1665 typval_T *rettv, |
2510 int copy, | 1666 int copy, |
3101 if (*arg != NUL) | 2257 if (*arg != NUL) |
3102 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) | 2258 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) |
3103 /* skip */ ; | 2259 /* skip */ ; |
3104 } | 2260 } |
3105 xp->xp_pattern = arg; | 2261 xp->xp_pattern = arg; |
3106 } | |
3107 | |
3108 /* | |
3109 * ":unlet[!] var1 ... " command. | |
3110 */ | |
3111 void | |
3112 ex_unlet(exarg_T *eap) | |
3113 { | |
3114 ex_unletlock(eap, eap->arg, 0); | |
3115 } | |
3116 | |
3117 /* | |
3118 * ":lockvar" and ":unlockvar" commands | |
3119 */ | |
3120 void | |
3121 ex_lockvar(exarg_T *eap) | |
3122 { | |
3123 char_u *arg = eap->arg; | |
3124 int deep = 2; | |
3125 | |
3126 if (eap->forceit) | |
3127 deep = -1; | |
3128 else if (vim_isdigit(*arg)) | |
3129 { | |
3130 deep = getdigits(&arg); | |
3131 arg = skipwhite(arg); | |
3132 } | |
3133 | |
3134 ex_unletlock(eap, arg, deep); | |
3135 } | |
3136 | |
3137 /* | |
3138 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. | |
3139 */ | |
3140 static void | |
3141 ex_unletlock( | |
3142 exarg_T *eap, | |
3143 char_u *argstart, | |
3144 int deep) | |
3145 { | |
3146 char_u *arg = argstart; | |
3147 char_u *name_end; | |
3148 int error = FALSE; | |
3149 lval_T lv; | |
3150 | |
3151 do | |
3152 { | |
3153 if (*arg == '$') | |
3154 { | |
3155 char_u *name = ++arg; | |
3156 | |
3157 if (get_env_len(&arg) == 0) | |
3158 { | |
3159 semsg(_(e_invarg2), name - 1); | |
3160 return; | |
3161 } | |
3162 vim_unsetenv(name); | |
3163 arg = skipwhite(arg); | |
3164 continue; | |
3165 } | |
3166 | |
3167 /* Parse the name and find the end. */ | |
3168 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0, | |
3169 FNE_CHECK_START); | |
3170 if (lv.ll_name == NULL) | |
3171 error = TRUE; /* error but continue parsing */ | |
3172 if (name_end == NULL || (!VIM_ISWHITE(*name_end) | |
3173 && !ends_excmd(*name_end))) | |
3174 { | |
3175 if (name_end != NULL) | |
3176 { | |
3177 emsg_severe = TRUE; | |
3178 emsg(_(e_trailing)); | |
3179 } | |
3180 if (!(eap->skip || error)) | |
3181 clear_lval(&lv); | |
3182 break; | |
3183 } | |
3184 | |
3185 if (!error && !eap->skip) | |
3186 { | |
3187 if (eap->cmdidx == CMD_unlet) | |
3188 { | |
3189 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) | |
3190 error = TRUE; | |
3191 } | |
3192 else | |
3193 { | |
3194 if (do_lock_var(&lv, name_end, deep, | |
3195 eap->cmdidx == CMD_lockvar) == FAIL) | |
3196 error = TRUE; | |
3197 } | |
3198 } | |
3199 | |
3200 if (!eap->skip) | |
3201 clear_lval(&lv); | |
3202 | |
3203 arg = skipwhite(name_end); | |
3204 } while (!ends_excmd(*arg)); | |
3205 | |
3206 eap->nextcmd = check_nextcmd(arg); | |
3207 } | |
3208 | |
3209 static int | |
3210 do_unlet_var( | |
3211 lval_T *lp, | |
3212 char_u *name_end, | |
3213 int forceit) | |
3214 { | |
3215 int ret = OK; | |
3216 int cc; | |
3217 | |
3218 if (lp->ll_tv == NULL) | |
3219 { | |
3220 cc = *name_end; | |
3221 *name_end = NUL; | |
3222 | |
3223 /* Normal name or expanded name. */ | |
3224 if (do_unlet(lp->ll_name, forceit) == FAIL) | |
3225 ret = FAIL; | |
3226 *name_end = cc; | |
3227 } | |
3228 else if ((lp->ll_list != NULL | |
3229 && var_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) | |
3230 || (lp->ll_dict != NULL | |
3231 && var_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) | |
3232 return FAIL; | |
3233 else if (lp->ll_range) | |
3234 { | |
3235 listitem_T *li; | |
3236 listitem_T *ll_li = lp->ll_li; | |
3237 int ll_n1 = lp->ll_n1; | |
3238 | |
3239 while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) | |
3240 { | |
3241 li = ll_li->li_next; | |
3242 if (var_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) | |
3243 return FAIL; | |
3244 ll_li = li; | |
3245 ++ll_n1; | |
3246 } | |
3247 | |
3248 /* Delete a range of List items. */ | |
3249 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) | |
3250 { | |
3251 li = lp->ll_li->li_next; | |
3252 listitem_remove(lp->ll_list, lp->ll_li); | |
3253 lp->ll_li = li; | |
3254 ++lp->ll_n1; | |
3255 } | |
3256 } | |
3257 else | |
3258 { | |
3259 if (lp->ll_list != NULL) | |
3260 /* unlet a List item. */ | |
3261 listitem_remove(lp->ll_list, lp->ll_li); | |
3262 else | |
3263 /* unlet a Dictionary item. */ | |
3264 dictitem_remove(lp->ll_dict, lp->ll_di); | |
3265 } | |
3266 | |
3267 return ret; | |
3268 } | |
3269 | |
3270 /* | |
3271 * "unlet" a variable. Return OK if it existed, FAIL if not. | |
3272 * When "forceit" is TRUE don't complain if the variable doesn't exist. | |
3273 */ | |
3274 int | |
3275 do_unlet(char_u *name, int forceit) | |
3276 { | |
3277 hashtab_T *ht; | |
3278 hashitem_T *hi; | |
3279 char_u *varname; | |
3280 dict_T *d; | |
3281 dictitem_T *di; | |
3282 | |
3283 ht = find_var_ht(name, &varname); | |
3284 if (ht != NULL && *varname != NUL) | |
3285 { | |
3286 d = get_current_funccal_dict(ht); | |
3287 if (d == NULL) | |
3288 { | |
3289 if (ht == &globvarht) | |
3290 d = &globvardict; | |
3291 else if (ht == &compat_hashtab) | |
3292 d = &vimvardict; | |
3293 else | |
3294 { | |
3295 di = find_var_in_ht(ht, *name, (char_u *)"", FALSE); | |
3296 d = di == NULL ? NULL : di->di_tv.vval.v_dict; | |
3297 } | |
3298 if (d == NULL) | |
3299 { | |
3300 internal_error("do_unlet()"); | |
3301 return FAIL; | |
3302 } | |
3303 } | |
3304 hi = hash_find(ht, varname); | |
3305 if (HASHITEM_EMPTY(hi)) | |
3306 hi = find_hi_in_scoped_ht(name, &ht); | |
3307 if (hi != NULL && !HASHITEM_EMPTY(hi)) | |
3308 { | |
3309 di = HI2DI(hi); | |
3310 if (var_check_fixed(di->di_flags, name, FALSE) | |
3311 || var_check_ro(di->di_flags, name, FALSE) | |
3312 || var_check_lock(d->dv_lock, name, FALSE)) | |
3313 return FAIL; | |
3314 | |
3315 delete_var(ht, hi); | |
3316 return OK; | |
3317 } | |
3318 } | |
3319 if (forceit) | |
3320 return OK; | |
3321 semsg(_("E108: No such variable: \"%s\""), name); | |
3322 return FAIL; | |
3323 } | |
3324 | |
3325 /* | |
3326 * Lock or unlock variable indicated by "lp". | |
3327 * "deep" is the levels to go (-1 for unlimited); | |
3328 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". | |
3329 */ | |
3330 static int | |
3331 do_lock_var( | |
3332 lval_T *lp, | |
3333 char_u *name_end, | |
3334 int deep, | |
3335 int lock) | |
3336 { | |
3337 int ret = OK; | |
3338 int cc; | |
3339 dictitem_T *di; | |
3340 | |
3341 if (deep == 0) /* nothing to do */ | |
3342 return OK; | |
3343 | |
3344 if (lp->ll_tv == NULL) | |
3345 { | |
3346 cc = *name_end; | |
3347 *name_end = NUL; | |
3348 | |
3349 /* Normal name or expanded name. */ | |
3350 di = find_var(lp->ll_name, NULL, TRUE); | |
3351 if (di == NULL) | |
3352 ret = FAIL; | |
3353 else if ((di->di_flags & DI_FLAGS_FIX) | |
3354 && di->di_tv.v_type != VAR_DICT | |
3355 && di->di_tv.v_type != VAR_LIST) | |
3356 /* For historic reasons this error is not given for a list or dict. | |
3357 * E.g., the b: dict could be locked/unlocked. */ | |
3358 semsg(_("E940: Cannot lock or unlock variable %s"), lp->ll_name); | |
3359 else | |
3360 { | |
3361 if (lock) | |
3362 di->di_flags |= DI_FLAGS_LOCK; | |
3363 else | |
3364 di->di_flags &= ~DI_FLAGS_LOCK; | |
3365 item_lock(&di->di_tv, deep, lock); | |
3366 } | |
3367 *name_end = cc; | |
3368 } | |
3369 else if (lp->ll_range) | |
3370 { | |
3371 listitem_T *li = lp->ll_li; | |
3372 | |
3373 /* (un)lock a range of List items. */ | |
3374 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) | |
3375 { | |
3376 item_lock(&li->li_tv, deep, lock); | |
3377 li = li->li_next; | |
3378 ++lp->ll_n1; | |
3379 } | |
3380 } | |
3381 else if (lp->ll_list != NULL) | |
3382 /* (un)lock a List item. */ | |
3383 item_lock(&lp->ll_li->li_tv, deep, lock); | |
3384 else | |
3385 /* (un)lock a Dictionary item. */ | |
3386 item_lock(&lp->ll_di->di_tv, deep, lock); | |
3387 | |
3388 return ret; | |
3389 } | |
3390 | |
3391 /* | |
3392 * Lock or unlock an item. "deep" is nr of levels to go. | |
3393 */ | |
3394 static void | |
3395 item_lock(typval_T *tv, int deep, int lock) | |
3396 { | |
3397 static int recurse = 0; | |
3398 list_T *l; | |
3399 listitem_T *li; | |
3400 dict_T *d; | |
3401 blob_T *b; | |
3402 hashitem_T *hi; | |
3403 int todo; | |
3404 | |
3405 if (recurse >= DICT_MAXNEST) | |
3406 { | |
3407 emsg(_("E743: variable nested too deep for (un)lock")); | |
3408 return; | |
3409 } | |
3410 if (deep == 0) | |
3411 return; | |
3412 ++recurse; | |
3413 | |
3414 /* lock/unlock the item itself */ | |
3415 if (lock) | |
3416 tv->v_lock |= VAR_LOCKED; | |
3417 else | |
3418 tv->v_lock &= ~VAR_LOCKED; | |
3419 | |
3420 switch (tv->v_type) | |
3421 { | |
3422 case VAR_UNKNOWN: | |
3423 case VAR_NUMBER: | |
3424 case VAR_STRING: | |
3425 case VAR_FUNC: | |
3426 case VAR_PARTIAL: | |
3427 case VAR_FLOAT: | |
3428 case VAR_SPECIAL: | |
3429 case VAR_JOB: | |
3430 case VAR_CHANNEL: | |
3431 break; | |
3432 | |
3433 case VAR_BLOB: | |
3434 if ((b = tv->vval.v_blob) != NULL) | |
3435 { | |
3436 if (lock) | |
3437 b->bv_lock |= VAR_LOCKED; | |
3438 else | |
3439 b->bv_lock &= ~VAR_LOCKED; | |
3440 } | |
3441 break; | |
3442 case VAR_LIST: | |
3443 if ((l = tv->vval.v_list) != NULL) | |
3444 { | |
3445 if (lock) | |
3446 l->lv_lock |= VAR_LOCKED; | |
3447 else | |
3448 l->lv_lock &= ~VAR_LOCKED; | |
3449 if (deep < 0 || deep > 1) | |
3450 /* recursive: lock/unlock the items the List contains */ | |
3451 for (li = l->lv_first; li != NULL; li = li->li_next) | |
3452 item_lock(&li->li_tv, deep - 1, lock); | |
3453 } | |
3454 break; | |
3455 case VAR_DICT: | |
3456 if ((d = tv->vval.v_dict) != NULL) | |
3457 { | |
3458 if (lock) | |
3459 d->dv_lock |= VAR_LOCKED; | |
3460 else | |
3461 d->dv_lock &= ~VAR_LOCKED; | |
3462 if (deep < 0 || deep > 1) | |
3463 { | |
3464 /* recursive: lock/unlock the items the List contains */ | |
3465 todo = (int)d->dv_hashtab.ht_used; | |
3466 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) | |
3467 { | |
3468 if (!HASHITEM_EMPTY(hi)) | |
3469 { | |
3470 --todo; | |
3471 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); | |
3472 } | |
3473 } | |
3474 } | |
3475 } | |
3476 } | |
3477 --recurse; | |
3478 } | 2262 } |
3479 | 2263 |
3480 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) | 2264 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) |
3481 /* | 2265 /* |
3482 * Delete all "menutrans_" variables. | 2266 * Delete all "menutrans_" variables. |
6869 /* | 5653 /* |
6870 * Get the length of an environment variable name. | 5654 * Get the length of an environment variable name. |
6871 * Advance "arg" to the first character after the name. | 5655 * Advance "arg" to the first character after the name. |
6872 * Return 0 for error. | 5656 * Return 0 for error. |
6873 */ | 5657 */ |
6874 static int | 5658 int |
6875 get_env_len(char_u **arg) | 5659 get_env_len(char_u **arg) |
6876 { | 5660 { |
6877 char_u *p; | 5661 char_u *p; |
6878 int len; | 5662 int len; |
6879 | 5663 |
6927 * Return -1 if curly braces expansion failed. | 5711 * Return -1 if curly braces expansion failed. |
6928 * Return 0 if something else is wrong. | 5712 * Return 0 if something else is wrong. |
6929 * If the name contains 'magic' {}'s, expand them and return the | 5713 * If the name contains 'magic' {}'s, expand them and return the |
6930 * expanded name in an allocated string via 'alias' - caller must free. | 5714 * expanded name in an allocated string via 'alias' - caller must free. |
6931 */ | 5715 */ |
6932 static int | 5716 int |
6933 get_name_len( | 5717 get_name_len( |
6934 char_u **arg, | 5718 char_u **arg, |
6935 char_u **alias, | 5719 char_u **alias, |
6936 int evaluate, | 5720 int evaluate, |
6937 int verbose) | 5721 int verbose) |
7450 STRCPY(newval + STRLEN(newval), " ++bad=drop"); | 6234 STRCPY(newval + STRLEN(newval), " ++bad=drop"); |
7451 else if (eap->bad_char != 0) | 6235 else if (eap->bad_char != 0) |
7452 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); | 6236 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); |
7453 vimvars[VV_CMDARG].vv_str = newval; | 6237 vimvars[VV_CMDARG].vv_str = newval; |
7454 return oldval; | 6238 return oldval; |
7455 } | |
7456 | |
7457 /* | |
7458 * Get the value of internal variable "name". | |
7459 * Return OK or FAIL. If OK is returned "rettv" must be cleared. | |
7460 */ | |
7461 static int | |
7462 get_var_tv( | |
7463 char_u *name, | |
7464 int len, /* length of "name" */ | |
7465 typval_T *rettv, /* NULL when only checking existence */ | |
7466 dictitem_T **dip, /* non-NULL when typval's dict item is needed */ | |
7467 int verbose, /* may give error message */ | |
7468 int no_autoload) /* do not use script autoloading */ | |
7469 { | |
7470 int ret = OK; | |
7471 typval_T *tv = NULL; | |
7472 dictitem_T *v; | |
7473 int cc; | |
7474 | |
7475 /* truncate the name, so that we can use strcmp() */ | |
7476 cc = name[len]; | |
7477 name[len] = NUL; | |
7478 | |
7479 /* | |
7480 * Check for user-defined variables. | |
7481 */ | |
7482 v = find_var(name, NULL, no_autoload); | |
7483 if (v != NULL) | |
7484 { | |
7485 tv = &v->di_tv; | |
7486 if (dip != NULL) | |
7487 *dip = v; | |
7488 } | |
7489 | |
7490 if (tv == NULL) | |
7491 { | |
7492 if (rettv != NULL && verbose) | |
7493 semsg(_(e_undefvar), name); | |
7494 ret = FAIL; | |
7495 } | |
7496 else if (rettv != NULL) | |
7497 copy_tv(tv, rettv); | |
7498 | |
7499 name[len] = cc; | |
7500 | |
7501 return ret; | |
7502 } | 6239 } |
7503 | 6240 |
7504 /* | 6241 /* |
7505 * Check if variable "name[len]" is a local variable or an argument. | 6242 * Check if variable "name[len]" is a local variable or an argument. |
7506 * If so, "*eval_lavars_used" is set to TRUE. | 6243 * If so, "*eval_lavars_used" is set to TRUE. |
8175 return &SCRIPT_VARS(current_sctx.sc_sid); | 6912 return &SCRIPT_VARS(current_sctx.sc_sid); |
8176 return NULL; | 6913 return NULL; |
8177 } | 6914 } |
8178 | 6915 |
8179 /* | 6916 /* |
8180 * Get the string value of a (global/local) variable. | |
8181 * Note: see tv_get_string() for how long the pointer remains valid. | |
8182 * Returns NULL when it doesn't exist. | |
8183 */ | |
8184 char_u * | |
8185 get_var_value(char_u *name) | |
8186 { | |
8187 dictitem_T *v; | |
8188 | |
8189 v = find_var(name, NULL, FALSE); | |
8190 if (v == NULL) | |
8191 return NULL; | |
8192 return tv_get_string(&v->di_tv); | |
8193 } | |
8194 | |
8195 /* | |
8196 * Allocate a new hashtab for a sourced script. It will be used while | 6917 * Allocate a new hashtab for a sourced script. It will be used while |
8197 * sourcing this script and when executing functions defined in the script. | 6918 * sourcing this script and when executing functions defined in the script. |
8198 */ | 6919 */ |
8199 void | 6920 void |
8200 new_script_vars(scid_T id) | 6921 new_script_vars(scid_T id) |
8254 { | 6975 { |
8255 /* Now the dict needs to be freed if no one else is using it, go back to | 6976 /* Now the dict needs to be freed if no one else is using it, go back to |
8256 * normal reference counting. */ | 6977 * normal reference counting. */ |
8257 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; | 6978 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; |
8258 dict_unref(dict); | 6979 dict_unref(dict); |
8259 } | |
8260 | |
8261 /* | |
8262 * Clean up a list of internal variables. | |
8263 * Frees all allocated variables and the value they contain. | |
8264 * Clears hashtab "ht", does not free it. | |
8265 */ | |
8266 void | |
8267 vars_clear(hashtab_T *ht) | |
8268 { | |
8269 vars_clear_ext(ht, TRUE); | |
8270 } | |
8271 | |
8272 /* | |
8273 * Like vars_clear(), but only free the value if "free_val" is TRUE. | |
8274 */ | |
8275 void | |
8276 vars_clear_ext(hashtab_T *ht, int free_val) | |
8277 { | |
8278 int todo; | |
8279 hashitem_T *hi; | |
8280 dictitem_T *v; | |
8281 | |
8282 hash_lock(ht); | |
8283 todo = (int)ht->ht_used; | |
8284 for (hi = ht->ht_array; todo > 0; ++hi) | |
8285 { | |
8286 if (!HASHITEM_EMPTY(hi)) | |
8287 { | |
8288 --todo; | |
8289 | |
8290 /* Free the variable. Don't remove it from the hashtab, | |
8291 * ht_array might change then. hash_clear() takes care of it | |
8292 * later. */ | |
8293 v = HI2DI(hi); | |
8294 if (free_val) | |
8295 clear_tv(&v->di_tv); | |
8296 if (v->di_flags & DI_FLAGS_ALLOC) | |
8297 vim_free(v); | |
8298 } | |
8299 } | |
8300 hash_clear(ht); | |
8301 ht->ht_used = 0; | |
8302 } | |
8303 | |
8304 /* | |
8305 * Delete a variable from hashtab "ht" at item "hi". | |
8306 * Clear the variable value and free the dictitem. | |
8307 */ | |
8308 static void | |
8309 delete_var(hashtab_T *ht, hashitem_T *hi) | |
8310 { | |
8311 dictitem_T *di = HI2DI(hi); | |
8312 | |
8313 hash_remove(ht, hi); | |
8314 clear_tv(&di->di_tv); | |
8315 vim_free(di); | |
8316 } | |
8317 | |
8318 /* | |
8319 * List the value of one internal variable. | |
8320 */ | |
8321 static void | |
8322 list_one_var(dictitem_T *v, char *prefix, int *first) | |
8323 { | |
8324 char_u *tofree; | |
8325 char_u *s; | |
8326 char_u numbuf[NUMBUFLEN]; | |
8327 | |
8328 s = echo_string(&v->di_tv, &tofree, numbuf, get_copyID()); | |
8329 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, | |
8330 s == NULL ? (char_u *)"" : s, first); | |
8331 vim_free(tofree); | |
8332 } | |
8333 | |
8334 static void | |
8335 list_one_var_a( | |
8336 char *prefix, | |
8337 char_u *name, | |
8338 int type, | |
8339 char_u *string, | |
8340 int *first) /* when TRUE clear rest of screen and set to FALSE */ | |
8341 { | |
8342 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ | |
8343 msg_start(); | |
8344 msg_puts(prefix); | |
8345 if (name != NULL) /* "a:" vars don't have a name stored */ | |
8346 msg_puts((char *)name); | |
8347 msg_putchar(' '); | |
8348 msg_advance(22); | |
8349 if (type == VAR_NUMBER) | |
8350 msg_putchar('#'); | |
8351 else if (type == VAR_FUNC || type == VAR_PARTIAL) | |
8352 msg_putchar('*'); | |
8353 else if (type == VAR_LIST) | |
8354 { | |
8355 msg_putchar('['); | |
8356 if (*string == '[') | |
8357 ++string; | |
8358 } | |
8359 else if (type == VAR_DICT) | |
8360 { | |
8361 msg_putchar('{'); | |
8362 if (*string == '{') | |
8363 ++string; | |
8364 } | |
8365 else | |
8366 msg_putchar(' '); | |
8367 | |
8368 msg_outtrans(string); | |
8369 | |
8370 if (type == VAR_FUNC || type == VAR_PARTIAL) | |
8371 msg_puts("()"); | |
8372 if (*first) | |
8373 { | |
8374 msg_clr_eos(); | |
8375 *first = FALSE; | |
8376 } | |
8377 } | |
8378 | |
8379 /* | |
8380 * Set variable "name" to value in "tv". | |
8381 * If the variable already exists, the value is updated. | |
8382 * Otherwise the variable is created. | |
8383 */ | |
8384 void | |
8385 set_var( | |
8386 char_u *name, | |
8387 typval_T *tv, | |
8388 int copy) // make copy of value in "tv" | |
8389 { | |
8390 set_var_const(name, tv, copy, FALSE); | |
8391 } | |
8392 | |
8393 /* | |
8394 * Set variable "name" to value in "tv". | |
8395 * If the variable already exists and "is_const" is FALSE the value is updated. | |
8396 * Otherwise the variable is created. | |
8397 */ | |
8398 static void | |
8399 set_var_const( | |
8400 char_u *name, | |
8401 typval_T *tv, | |
8402 int copy, // make copy of value in "tv" | |
8403 int is_const) // disallow to modify existing variable | |
8404 { | |
8405 dictitem_T *v; | |
8406 char_u *varname; | |
8407 hashtab_T *ht; | |
8408 | |
8409 ht = find_var_ht(name, &varname); | |
8410 if (ht == NULL || *varname == NUL) | |
8411 { | |
8412 semsg(_(e_illvar), name); | |
8413 return; | |
8414 } | |
8415 v = find_var_in_ht(ht, 0, varname, TRUE); | |
8416 | |
8417 /* Search in parent scope which is possible to reference from lambda */ | |
8418 if (v == NULL) | |
8419 v = find_var_in_scoped_ht(name, TRUE); | |
8420 | |
8421 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) | |
8422 && var_check_func_name(name, v == NULL)) | |
8423 return; | |
8424 | |
8425 if (v != NULL) | |
8426 { | |
8427 if (is_const) | |
8428 { | |
8429 emsg(_(e_cannot_mod)); | |
8430 return; | |
8431 } | |
8432 | |
8433 /* existing variable, need to clear the value */ | |
8434 if (var_check_ro(v->di_flags, name, FALSE) | |
8435 || var_check_lock(v->di_tv.v_lock, name, FALSE)) | |
8436 return; | |
8437 | |
8438 /* | |
8439 * Handle setting internal v: variables separately where needed to | |
8440 * prevent changing the type. | |
8441 */ | |
8442 if (ht == &vimvarht) | |
8443 { | |
8444 if (v->di_tv.v_type == VAR_STRING) | |
8445 { | |
8446 VIM_CLEAR(v->di_tv.vval.v_string); | |
8447 if (copy || tv->v_type != VAR_STRING) | |
8448 { | |
8449 char_u *val = tv_get_string(tv); | |
8450 | |
8451 // Careful: when assigning to v:errmsg and tv_get_string() | |
8452 // causes an error message the variable will alrady be set. | |
8453 if (v->di_tv.vval.v_string == NULL) | |
8454 v->di_tv.vval.v_string = vim_strsave(val); | |
8455 } | |
8456 else | |
8457 { | |
8458 /* Take over the string to avoid an extra alloc/free. */ | |
8459 v->di_tv.vval.v_string = tv->vval.v_string; | |
8460 tv->vval.v_string = NULL; | |
8461 } | |
8462 return; | |
8463 } | |
8464 else if (v->di_tv.v_type == VAR_NUMBER) | |
8465 { | |
8466 v->di_tv.vval.v_number = tv_get_number(tv); | |
8467 if (STRCMP(varname, "searchforward") == 0) | |
8468 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); | |
8469 #ifdef FEAT_SEARCH_EXTRA | |
8470 else if (STRCMP(varname, "hlsearch") == 0) | |
8471 { | |
8472 no_hlsearch = !v->di_tv.vval.v_number; | |
8473 redraw_all_later(SOME_VALID); | |
8474 } | |
8475 #endif | |
8476 return; | |
8477 } | |
8478 else if (v->di_tv.v_type != tv->v_type) | |
8479 { | |
8480 semsg(_("E963: setting %s to value with wrong type"), name); | |
8481 return; | |
8482 } | |
8483 } | |
8484 | |
8485 clear_tv(&v->di_tv); | |
8486 } | |
8487 else /* add a new variable */ | |
8488 { | |
8489 // Can't add "v:" or "a:" variable. | |
8490 if (ht == &vimvarht || ht == get_funccal_args_ht()) | |
8491 { | |
8492 semsg(_(e_illvar), name); | |
8493 return; | |
8494 } | |
8495 | |
8496 // Make sure the variable name is valid. | |
8497 if (!valid_varname(varname)) | |
8498 return; | |
8499 | |
8500 v = alloc(sizeof(dictitem_T) + STRLEN(varname)); | |
8501 if (v == NULL) | |
8502 return; | |
8503 STRCPY(v->di_key, varname); | |
8504 if (hash_add(ht, DI2HIKEY(v)) == FAIL) | |
8505 { | |
8506 vim_free(v); | |
8507 return; | |
8508 } | |
8509 v->di_flags = DI_FLAGS_ALLOC; | |
8510 if (is_const) | |
8511 v->di_flags |= DI_FLAGS_LOCK; | |
8512 } | |
8513 | |
8514 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) | |
8515 copy_tv(tv, &v->di_tv); | |
8516 else | |
8517 { | |
8518 v->di_tv = *tv; | |
8519 v->di_tv.v_lock = 0; | |
8520 init_tv(tv); | |
8521 } | |
8522 | |
8523 if (is_const) | |
8524 v->di_tv.v_lock |= VAR_LOCKED; | |
8525 } | |
8526 | |
8527 /* | |
8528 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. | |
8529 * Also give an error message. | |
8530 */ | |
8531 int | |
8532 var_check_ro(int flags, char_u *name, int use_gettext) | |
8533 { | |
8534 if (flags & DI_FLAGS_RO) | |
8535 { | |
8536 semsg(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name); | |
8537 return TRUE; | |
8538 } | |
8539 if ((flags & DI_FLAGS_RO_SBX) && sandbox) | |
8540 { | |
8541 semsg(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name); | |
8542 return TRUE; | |
8543 } | |
8544 return FALSE; | |
8545 } | |
8546 | |
8547 /* | |
8548 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. | |
8549 * Also give an error message. | |
8550 */ | |
8551 int | |
8552 var_check_fixed(int flags, char_u *name, int use_gettext) | |
8553 { | |
8554 if (flags & DI_FLAGS_FIX) | |
8555 { | |
8556 semsg(_("E795: Cannot delete variable %s"), | |
8557 use_gettext ? (char_u *)_(name) : name); | |
8558 return TRUE; | |
8559 } | |
8560 return FALSE; | |
8561 } | |
8562 | |
8563 /* | |
8564 * Check if a funcref is assigned to a valid variable name. | |
8565 * Return TRUE and give an error if not. | |
8566 */ | |
8567 int | |
8568 var_check_func_name( | |
8569 char_u *name, /* points to start of variable name */ | |
8570 int new_var) /* TRUE when creating the variable */ | |
8571 { | |
8572 /* Allow for w: b: s: and t:. */ | |
8573 if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':') | |
8574 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') | |
8575 ? name[2] : name[0])) | |
8576 { | |
8577 semsg(_("E704: Funcref variable name must start with a capital: %s"), | |
8578 name); | |
8579 return TRUE; | |
8580 } | |
8581 /* Don't allow hiding a function. When "v" is not NULL we might be | |
8582 * assigning another function to the same var, the type is checked | |
8583 * below. */ | |
8584 if (new_var && function_exists(name, FALSE)) | |
8585 { | |
8586 semsg(_("E705: Variable name conflicts with existing function: %s"), | |
8587 name); | |
8588 return TRUE; | |
8589 } | |
8590 return FALSE; | |
8591 } | |
8592 | |
8593 /* | |
8594 * Return TRUE if "flags" indicates variable "name" is locked (immutable). | |
8595 * Also give an error message, using "name" or _("name") when use_gettext is | |
8596 * TRUE. | |
8597 */ | |
8598 int | |
8599 var_check_lock(int lock, char_u *name, int use_gettext) | |
8600 { | |
8601 if (lock & VAR_LOCKED) | |
8602 { | |
8603 semsg(_("E741: Value is locked: %s"), | |
8604 name == NULL ? (char_u *)_("Unknown") | |
8605 : use_gettext ? (char_u *)_(name) | |
8606 : name); | |
8607 return TRUE; | |
8608 } | |
8609 if (lock & VAR_FIXED) | |
8610 { | |
8611 semsg(_("E742: Cannot change value of %s"), | |
8612 name == NULL ? (char_u *)_("Unknown") | |
8613 : use_gettext ? (char_u *)_(name) | |
8614 : name); | |
8615 return TRUE; | |
8616 } | |
8617 return FALSE; | |
8618 } | 6980 } |
8619 | 6981 |
8620 /* | 6982 /* |
8621 * Return TRUE if typeval "tv" and its value are set to be locked (immutable). | 6983 * Return TRUE if typeval "tv" and its value are set to be locked (immutable). |
8622 * Also give an error message, using "name" or _("name") when use_gettext is | 6984 * Also give an error message, using "name" or _("name") when use_gettext is |
8644 default: | 7006 default: |
8645 break; | 7007 break; |
8646 } | 7008 } |
8647 return var_check_lock(tv->v_lock, name, use_gettext) | 7009 return var_check_lock(tv->v_lock, name, use_gettext) |
8648 || (lock != 0 && var_check_lock(lock, name, use_gettext)); | 7010 || (lock != 0 && var_check_lock(lock, name, use_gettext)); |
8649 } | |
8650 | |
8651 /* | |
8652 * Check if a variable name is valid. | |
8653 * Return FALSE and give an error if not. | |
8654 */ | |
8655 int | |
8656 valid_varname(char_u *varname) | |
8657 { | |
8658 char_u *p; | |
8659 | |
8660 for (p = varname; *p != NUL; ++p) | |
8661 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) | |
8662 && *p != AUTOLOAD_CHAR) | |
8663 { | |
8664 semsg(_(e_illvar), varname); | |
8665 return FALSE; | |
8666 } | |
8667 return TRUE; | |
8668 } | 7011 } |
8669 | 7012 |
8670 /* | 7013 /* |
8671 * Copy the values from typval_T "from" to typval_T "to". | 7014 * Copy the values from typval_T "from" to typval_T "to". |
8672 * When needed allocates string or increases reference count. | 7015 * When needed allocates string or increases reference count. |
9248 | 7591 |
9249 return wp; | 7592 return wp; |
9250 } | 7593 } |
9251 | 7594 |
9252 /* | 7595 /* |
9253 * getwinvar() and gettabwinvar() | |
9254 */ | |
9255 void | |
9256 getwinvar( | |
9257 typval_T *argvars, | |
9258 typval_T *rettv, | |
9259 int off) /* 1 for gettabwinvar() */ | |
9260 { | |
9261 win_T *win; | |
9262 char_u *varname; | |
9263 dictitem_T *v; | |
9264 tabpage_T *tp = NULL; | |
9265 int done = FALSE; | |
9266 win_T *oldcurwin; | |
9267 tabpage_T *oldtabpage; | |
9268 int need_switch_win; | |
9269 | |
9270 if (off == 1) | |
9271 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); | |
9272 else | |
9273 tp = curtab; | |
9274 win = find_win_by_nr(&argvars[off], tp); | |
9275 varname = tv_get_string_chk(&argvars[off + 1]); | |
9276 ++emsg_off; | |
9277 | |
9278 rettv->v_type = VAR_STRING; | |
9279 rettv->vval.v_string = NULL; | |
9280 | |
9281 if (win != NULL && varname != NULL) | |
9282 { | |
9283 /* Set curwin to be our win, temporarily. Also set the tabpage, | |
9284 * otherwise the window is not valid. Only do this when needed, | |
9285 * autocommands get blocked. */ | |
9286 need_switch_win = !(tp == curtab && win == curwin); | |
9287 if (!need_switch_win | |
9288 || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) | |
9289 { | |
9290 if (*varname == '&') | |
9291 { | |
9292 if (varname[1] == NUL) | |
9293 { | |
9294 /* get all window-local options in a dict */ | |
9295 dict_T *opts = get_winbuf_options(FALSE); | |
9296 | |
9297 if (opts != NULL) | |
9298 { | |
9299 rettv_dict_set(rettv, opts); | |
9300 done = TRUE; | |
9301 } | |
9302 } | |
9303 else if (get_option_tv(&varname, rettv, 1) == OK) | |
9304 /* window-local-option */ | |
9305 done = TRUE; | |
9306 } | |
9307 else | |
9308 { | |
9309 /* Look up the variable. */ | |
9310 /* Let getwinvar({nr}, "") return the "w:" dictionary. */ | |
9311 v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', | |
9312 varname, FALSE); | |
9313 if (v != NULL) | |
9314 { | |
9315 copy_tv(&v->di_tv, rettv); | |
9316 done = TRUE; | |
9317 } | |
9318 } | |
9319 } | |
9320 | |
9321 if (need_switch_win) | |
9322 /* restore previous notion of curwin */ | |
9323 restore_win(oldcurwin, oldtabpage, TRUE); | |
9324 } | |
9325 | |
9326 if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) | |
9327 /* use the default return value */ | |
9328 copy_tv(&argvars[off + 2], rettv); | |
9329 | |
9330 --emsg_off; | |
9331 } | |
9332 | |
9333 /* | |
9334 * "setwinvar()" and "settabwinvar()" functions | |
9335 */ | |
9336 void | |
9337 setwinvar(typval_T *argvars, typval_T *rettv UNUSED, int off) | |
9338 { | |
9339 win_T *win; | |
9340 win_T *save_curwin; | |
9341 tabpage_T *save_curtab; | |
9342 int need_switch_win; | |
9343 char_u *varname, *winvarname; | |
9344 typval_T *varp; | |
9345 char_u nbuf[NUMBUFLEN]; | |
9346 tabpage_T *tp = NULL; | |
9347 | |
9348 if (check_secure()) | |
9349 return; | |
9350 | |
9351 if (off == 1) | |
9352 tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); | |
9353 else | |
9354 tp = curtab; | |
9355 win = find_win_by_nr(&argvars[off], tp); | |
9356 varname = tv_get_string_chk(&argvars[off + 1]); | |
9357 varp = &argvars[off + 2]; | |
9358 | |
9359 if (win != NULL && varname != NULL && varp != NULL) | |
9360 { | |
9361 need_switch_win = !(tp == curtab && win == curwin); | |
9362 if (!need_switch_win | |
9363 || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) | |
9364 { | |
9365 if (*varname == '&') | |
9366 { | |
9367 long numval; | |
9368 char_u *strval; | |
9369 int error = FALSE; | |
9370 | |
9371 ++varname; | |
9372 numval = (long)tv_get_number_chk(varp, &error); | |
9373 strval = tv_get_string_buf_chk(varp, nbuf); | |
9374 if (!error && strval != NULL) | |
9375 set_option_value(varname, numval, strval, OPT_LOCAL); | |
9376 } | |
9377 else | |
9378 { | |
9379 winvarname = alloc(STRLEN(varname) + 3); | |
9380 if (winvarname != NULL) | |
9381 { | |
9382 STRCPY(winvarname, "w:"); | |
9383 STRCPY(winvarname + 2, varname); | |
9384 set_var(winvarname, varp, TRUE); | |
9385 vim_free(winvarname); | |
9386 } | |
9387 } | |
9388 } | |
9389 if (need_switch_win) | |
9390 restore_win(save_curwin, save_curtab, TRUE); | |
9391 } | |
9392 } | |
9393 | |
9394 /* | |
9395 * Skip over the name of an option: "&option", "&g:option" or "&l:option". | 7596 * Skip over the name of an option: "&option", "&g:option" or "&l:option". |
9396 * "arg" points to the "&" or '+' when called, to "option" when returning. | 7597 * "arg" points to the "&" or '+' when called, to "option" when returning. |
9397 * Returns NULL when no option name found. Otherwise pointer to the char | 7598 * Returns NULL when no option name found. Otherwise pointer to the char |
9398 * after the option name. | 7599 * after the option name. |
9399 */ | 7600 */ |
9400 static char_u * | 7601 char_u * |
9401 find_option_end(char_u **arg, int *opt_flags) | 7602 find_option_end(char_u **arg, int *opt_flags) |
9402 { | 7603 { |
9403 char_u *p = *arg; | 7604 char_u *p = *arg; |
9404 | 7605 |
9405 ++p; | 7606 ++p; |
9793 ret = tv2string(arg, &tofree, numbuf, 0); | 7994 ret = tv2string(arg, &tofree, numbuf, 0); |
9794 /* Make a copy if we have a value but it's not in allocated memory. */ | 7995 /* Make a copy if we have a value but it's not in allocated memory. */ |
9795 if (ret != NULL && tofree == NULL) | 7996 if (ret != NULL && tofree == NULL) |
9796 ret = vim_strsave(ret); | 7997 ret = vim_strsave(ret); |
9797 return ret; | 7998 return ret; |
9798 } | |
9799 | |
9800 int | |
9801 var_exists(char_u *var) | |
9802 { | |
9803 char_u *name; | |
9804 char_u *tofree; | |
9805 typval_T tv; | |
9806 int len = 0; | |
9807 int n = FALSE; | |
9808 | |
9809 /* get_name_len() takes care of expanding curly braces */ | |
9810 name = var; | |
9811 len = get_name_len(&var, &tofree, TRUE, FALSE); | |
9812 if (len > 0) | |
9813 { | |
9814 if (tofree != NULL) | |
9815 name = tofree; | |
9816 n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK); | |
9817 if (n) | |
9818 { | |
9819 /* handle d.key, l[idx], f(expr) */ | |
9820 n = (handle_subscript(&var, &tv, TRUE, FALSE, name, &name) == OK); | |
9821 if (n) | |
9822 clear_tv(&tv); | |
9823 } | |
9824 } | |
9825 if (*var != NUL) | |
9826 n = FALSE; | |
9827 | |
9828 vim_free(tofree); | |
9829 return n; | |
9830 } | 7999 } |
9831 | 8000 |
9832 #endif /* FEAT_EVAL */ | 8001 #endif /* FEAT_EVAL */ |
9833 | 8002 |
9834 | 8003 |