Mercurial > vim
comparison src/eval.c @ 124:f455396f3c3f v7.0043
updated for version 7.0043
author | vimboss |
---|---|
date | Fri, 21 Jan 2005 11:56:39 +0000 |
parents | 86d71ae0c85a |
children | 3e7d17e425b0 |
comparison
equal
deleted
inserted
replaced
123:f67f8a8d81ba | 124:f455396f3c3f |
---|---|
64 * The "tv" must come first, so that this can be used as a "typeval" as well. | 64 * The "tv" must come first, so that this can be used as a "typeval" as well. |
65 */ | 65 */ |
66 typedef struct | 66 typedef struct |
67 { | 67 { |
68 typeval tv; /* type and value of the variable */ | 68 typeval tv; /* type and value of the variable */ |
69 char_u *v_name; /* name of variable */ | 69 char_u v_name[1]; /* name of variable (actually longer) */ |
70 } var; | 70 } var; |
71 | 71 |
72 typedef var * VAR; | 72 typedef var * VAR; |
73 | |
74 /* | |
75 * In a hashtable item "hi_key" points to "v_name" in a variable. | |
76 * This avoids adding a pointer to the hashtable item. | |
77 * VAR2HIKEY() converts a var pointer to a hashitem key pointer. | |
78 * HIKEY2VAR() converts a hashitem key pointer to a var pointer. | |
79 * HI2VAR() converts a hashitem pointer to a var pointer. | |
80 */ | |
81 static var dumvar; | |
82 #define VAR2HIKEY(v) ((v)->v_name) | |
83 #define HIKEY2VAR(p) ((VAR)(p - (dumvar.v_name - (char_u *)&dumvar.tv))) | |
84 #define HI2VAR(hi) HIKEY2VAR((hi)->hi_key) | |
73 | 85 |
74 /* | 86 /* |
75 * Structure to hold an item of a list: an internal variable without a name. | 87 * Structure to hold an item of a list: an internal variable without a name. |
76 */ | 88 */ |
77 struct listitem_S | 89 struct listitem_S |
125 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. | 137 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. |
126 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. | 138 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. |
127 * HI2DI() converts a hashitem pointer to a dictitem pointer. | 139 * HI2DI() converts a hashitem pointer to a dictitem pointer. |
128 */ | 140 */ |
129 static dictitem dumdi; | 141 static dictitem dumdi; |
130 #define DI2HIKEY(p) ((p)->di_key) | 142 #define DI2HIKEY(di) ((di)->di_key) |
131 #define HIKEY2DI(p) ((dictitem *)(p - (dumdi.di_key - (char_u *)&dumdi.di_tv))) | 143 #define HIKEY2DI(p) ((dictitem *)(p - (dumdi.di_key - (char_u *)&dumdi.di_tv))) |
132 #define HI2DI(p) HIKEY2DI((p)->hi_key) | 144 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) |
133 | 145 |
134 /* | 146 /* |
135 * Structure to hold info about a Dictionary. | 147 * Structure to hold info about a Dictionary. |
136 */ | 148 */ |
137 struct dictvar_S | 149 struct dictvar_S |
206 static char *e_letwrong = N_("E734: Wrong variable type for %s="); | 218 static char *e_letwrong = N_("E734: Wrong variable type for %s="); |
207 | 219 |
208 /* | 220 /* |
209 * All user-defined global variables are stored in "variables". | 221 * All user-defined global variables are stored in "variables". |
210 */ | 222 */ |
211 garray_T variables = {0, 0, sizeof(var), 4, NULL}; | 223 hashtable variables; |
212 | 224 |
213 /* | 225 /* |
214 * Array to hold an array with variables local to each sourced script. | 226 * Array to hold the hashtable with variables local to each sourced script. |
215 */ | 227 */ |
216 static garray_T ga_scripts = {0, 0, sizeof(garray_T), 4, NULL}; | 228 static garray_T ga_scripts = {0, 0, sizeof(hashtable), 4, NULL}; |
217 #define SCRIPT_VARS(id) (((garray_T *)ga_scripts.ga_data)[(id) - 1]) | 229 #define SCRIPT_VARS(id) (((hashtable *)ga_scripts.ga_data)[(id) - 1]) |
218 | |
219 | |
220 #define VAR_ENTRY(idx) (((VAR)(variables.ga_data))[idx]) | |
221 #define VAR_GAP_ENTRY(idx, gap) (((VAR)((gap)->ga_data))[idx]) | |
222 #define BVAR_ENTRY(idx) (((VAR)(curbuf->b_vars.ga_data))[idx]) | |
223 #define WVAR_ENTRY(idx) (((VAR)(curwin->w_vars.ga_data))[idx]) | |
224 | 230 |
225 static int echo_attr = 0; /* attributes used for ":echo" */ | 231 static int echo_attr = 0; /* attributes used for ":echo" */ |
226 | 232 |
227 /* Values for trans_function_name() argument: */ | 233 /* Values for trans_function_name() argument: */ |
228 #define TFN_INT 1 /* internal function name OK */ | 234 #define TFN_INT 1 /* internal function name OK */ |
271 int argcount; /* nr of arguments */ | 277 int argcount; /* nr of arguments */ |
272 typeval *argvars; /* arguments */ | 278 typeval *argvars; /* arguments */ |
273 var a0_var; /* "a:0" variable */ | 279 var a0_var; /* "a:0" variable */ |
274 var firstline; /* "a:firstline" variable */ | 280 var firstline; /* "a:firstline" variable */ |
275 var lastline; /* "a:lastline" variable */ | 281 var lastline; /* "a:lastline" variable */ |
276 garray_T l_vars; /* local function variables */ | 282 hashtable l_vars; /* local function variables */ |
277 typeval *rettv; /* return value */ | 283 typeval *rettv; /* return value */ |
278 linenr_T breakpoint; /* next line with breakpoint or zero */ | 284 linenr_T breakpoint; /* next line with breakpoint or zero */ |
279 int dbg_tick; /* debug_tick when breakpoint was set */ | 285 int dbg_tick; /* debug_tick when breakpoint was set */ |
280 int level; /* top nesting level of executed function */ | 286 int level; /* top nesting level of executed function */ |
281 }; | 287 }; |
298 { | 304 { |
299 dictvar *fd_dict; /* Dictionary used */ | 305 dictvar *fd_dict; /* Dictionary used */ |
300 char_u *fd_newkey; /* new key in "dict" */ | 306 char_u *fd_newkey; /* new key in "dict" */ |
301 dictitem *fd_di; /* Dictionary item used */ | 307 dictitem *fd_di; /* Dictionary item used */ |
302 } funcdict; | 308 } funcdict; |
309 | |
310 | |
311 /* | |
312 * Initialize the global variables. | |
313 */ | |
314 void | |
315 eval_init() | |
316 { | |
317 hash_init(&variables); | |
318 } | |
303 | 319 |
304 /* | 320 /* |
305 * Return the name of the executed function. | 321 * Return the name of the executed function. |
306 */ | 322 */ |
307 char_u * | 323 char_u * |
648 | 664 |
649 static win_T *find_win_by_nr __ARGS((typeval *vp)); | 665 static win_T *find_win_by_nr __ARGS((typeval *vp)); |
650 static pos_T *var2fpos __ARGS((typeval *varp, int lnum)); | 666 static pos_T *var2fpos __ARGS((typeval *varp, int lnum)); |
651 static int get_env_len __ARGS((char_u **arg)); | 667 static int get_env_len __ARGS((char_u **arg)); |
652 static int get_id_len __ARGS((char_u **arg)); | 668 static int get_id_len __ARGS((char_u **arg)); |
653 static int get_func_len __ARGS((char_u **arg, char_u **alias, int evaluate)); | 669 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate)); |
654 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int incl_br)); | 670 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int incl_br)); |
655 static int eval_isnamec __ARGS((int c)); | 671 static int eval_isnamec __ARGS((int c)); |
656 static int find_vim_var __ARGS((char_u *name, int len)); | 672 static int find_vim_var __ARGS((char_u *name, int len)); |
657 static int get_var_tv __ARGS((char_u *name, int len, typeval *rettv)); | 673 static int get_var_tv __ARGS((char_u *name, int len, typeval *rettv)); |
658 static typeval *alloc_tv __ARGS((void)); | 674 static typeval *alloc_tv __ARGS((void)); |
662 static void init_tv __ARGS((typeval *varp)); | 678 static void init_tv __ARGS((typeval *varp)); |
663 static long get_tv_number __ARGS((typeval *varp)); | 679 static long get_tv_number __ARGS((typeval *varp)); |
664 static linenr_T get_tv_lnum __ARGS((typeval *argvars)); | 680 static linenr_T get_tv_lnum __ARGS((typeval *argvars)); |
665 static char_u *get_tv_string __ARGS((typeval *varp)); | 681 static char_u *get_tv_string __ARGS((typeval *varp)); |
666 static char_u *get_tv_string_buf __ARGS((typeval *varp, char_u *buf)); | 682 static char_u *get_tv_string_buf __ARGS((typeval *varp, char_u *buf)); |
667 static VAR find_var __ARGS((char_u *name, int writing)); | 683 static VAR find_var __ARGS((char_u *name, hashtable **htp)); |
668 static VAR find_var_in_ga __ARGS((garray_T *gap, char_u *varname)); | 684 static VAR find_var_in_ht __ARGS((hashtable *ht, char_u *varname)); |
669 static garray_T *find_var_ga __ARGS((char_u *name, char_u **varname)); | 685 static hashtable *find_var_ht __ARGS((char_u *name, char_u **varname)); |
670 static void clear_var __ARGS((VAR v)); | 686 static void delete_var __ARGS((hashtable *ht, hashitem *hi)); |
671 static void list_one_var __ARGS((VAR v, char_u *prefix)); | 687 static void list_one_var __ARGS((VAR v, char_u *prefix)); |
672 static void list_vim_var __ARGS((int i)); | 688 static void list_vim_var __ARGS((int i)); |
673 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); | 689 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); |
674 static void set_var __ARGS((char_u *name, typeval *varp, int copy)); | 690 static void set_var __ARGS((char_u *name, typeval *varp, int copy)); |
675 static void copy_tv __ARGS((typeval *from, typeval *to)); | 691 static void copy_tv __ARGS((typeval *from, typeval *to)); |
685 static void func_free __ARGS((ufunc_T *fp)); | 701 static void func_free __ARGS((ufunc_T *fp)); |
686 static void func_unref __ARGS((char_u *name)); | 702 static void func_unref __ARGS((char_u *name)); |
687 static void func_ref __ARGS((char_u *name)); | 703 static void func_ref __ARGS((char_u *name)); |
688 static void call_user_func __ARGS((ufunc_T *fp, int argcount, typeval *argvars, typeval *rettv, linenr_T firstline, linenr_T lastline, dictvar *selfdict)); | 704 static void call_user_func __ARGS((ufunc_T *fp, int argcount, typeval *argvars, typeval *rettv, linenr_T firstline, linenr_T lastline, dictvar *selfdict)); |
689 | 705 |
690 #define get_var_string(p) get_tv_string(&(p)->tv) | |
691 #define get_var_string_buf(p, b) get_tv_string_buf(&(p)->tv, (b)) | |
692 #define get_var_number(p) get_tv_number(&((p)->tv)) | |
693 | |
694 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); | 706 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); |
695 | 707 |
696 static int ex_let_vars __ARGS((char_u *arg, typeval *tv, int copy, int semicolon, int var_count, char_u *nextchars)); | 708 static int ex_let_vars __ARGS((char_u *arg, typeval *tv, int copy, int semicolon, int var_count, char_u *nextchars)); |
697 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); | 709 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); |
698 static char_u *skip_var_one __ARGS((char_u *arg)); | 710 static char_u *skip_var_one __ARGS((char_u *arg)); |
699 static void list_all_vars __ARGS((void)); | 711 static void list_hashtable_vars __ARGS((hashtable *ht, char_u *prefix)); |
712 static void list_glob_vars __ARGS((void)); | |
713 static void list_buf_vars __ARGS((void)); | |
714 static void list_win_vars __ARGS((void)); | |
715 static void list_vim_vars __ARGS((void)); | |
700 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); | 716 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); |
701 static char_u *ex_let_one __ARGS((char_u *arg, typeval *tv, int copy, char_u *endchars, char_u *op)); | 717 static char_u *ex_let_one __ARGS((char_u *arg, typeval *tv, int copy, char_u *endchars, char_u *op)); |
702 static int check_changedtick __ARGS((char_u *arg)); | 718 static int check_changedtick __ARGS((char_u *arg)); |
703 static char_u *get_lval __ARGS((char_u *name, typeval *rettv, lval *lp, int unlet, int skip, int quiet)); | 719 static char_u *get_lval __ARGS((char_u *name, typeval *rettv, lval *lp, int unlet, int skip, int quiet)); |
704 static void clear_lval __ARGS((lval *lp)); | 720 static void clear_lval __ARGS((lval *lp)); |
1236 EMSG(_(e_invarg)); | 1252 EMSG(_(e_invarg)); |
1237 else if (!ends_excmd(*arg)) | 1253 else if (!ends_excmd(*arg)) |
1238 /* ":let var1 var2" */ | 1254 /* ":let var1 var2" */ |
1239 arg = list_arg_vars(eap, arg); | 1255 arg = list_arg_vars(eap, arg); |
1240 else if (!eap->skip) | 1256 else if (!eap->skip) |
1257 { | |
1241 /* ":let" */ | 1258 /* ":let" */ |
1242 list_all_vars(); | 1259 list_glob_vars(); |
1260 list_buf_vars(); | |
1261 list_win_vars(); | |
1262 list_vim_vars(); | |
1263 } | |
1243 eap->nextcmd = check_nextcmd(arg); | 1264 eap->nextcmd = check_nextcmd(arg); |
1244 } | 1265 } |
1245 else | 1266 else |
1246 { | 1267 { |
1247 op[0] = '='; | 1268 op[0] = '='; |
1431 if (vim_strchr((char_u *)"$@&", *arg) != NULL) | 1452 if (vim_strchr((char_u *)"$@&", *arg) != NULL) |
1432 ++arg; | 1453 ++arg; |
1433 return find_name_end(arg, NULL, NULL, TRUE); | 1454 return find_name_end(arg, NULL, NULL, TRUE); |
1434 } | 1455 } |
1435 | 1456 |
1436 static void | 1457 /* |
1437 list_all_vars() | 1458 * List variables for hashtable "ht" with prefix "prefix". |
1459 */ | |
1460 static void | |
1461 list_hashtable_vars(ht, prefix) | |
1462 hashtable *ht; | |
1463 char_u *prefix; | |
1464 { | |
1465 hashitem *hi; | |
1466 int todo; | |
1467 | |
1468 todo = ht->ht_used; | |
1469 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) | |
1470 { | |
1471 if (!HASHITEM_EMPTY(hi)) | |
1472 { | |
1473 --todo; | |
1474 list_one_var(HI2VAR(hi), prefix); | |
1475 } | |
1476 } | |
1477 } | |
1478 | |
1479 /* | |
1480 * List global variables. | |
1481 */ | |
1482 static void | |
1483 list_glob_vars() | |
1484 { | |
1485 list_hashtable_vars(&variables, (char_u *)""); | |
1486 } | |
1487 | |
1488 /* | |
1489 * List buffer variables. | |
1490 */ | |
1491 static void | |
1492 list_buf_vars() | |
1493 { | |
1494 list_hashtable_vars(&curbuf->b_vars, (char_u *)"b:"); | |
1495 } | |
1496 | |
1497 /* | |
1498 * List window variables. | |
1499 */ | |
1500 static void | |
1501 list_win_vars() | |
1502 { | |
1503 list_hashtable_vars(&curwin->w_vars, (char_u *)"w:"); | |
1504 } | |
1505 | |
1506 /* | |
1507 * List Vim variables. | |
1508 */ | |
1509 static void | |
1510 list_vim_vars() | |
1438 { | 1511 { |
1439 int i; | 1512 int i; |
1440 | 1513 |
1441 /* | |
1442 * List all variables. | |
1443 */ | |
1444 for (i = 0; i < variables.ga_len && !got_int; ++i) | |
1445 if (VAR_ENTRY(i).v_name != NULL) | |
1446 list_one_var(&VAR_ENTRY(i), (char_u *)""); | |
1447 for (i = 0; i < curbuf->b_vars.ga_len && !got_int; ++i) | |
1448 if (BVAR_ENTRY(i).v_name != NULL) | |
1449 list_one_var(&BVAR_ENTRY(i), (char_u *)"b:"); | |
1450 for (i = 0; i < curwin->w_vars.ga_len && !got_int; ++i) | |
1451 if (WVAR_ENTRY(i).v_name != NULL) | |
1452 list_one_var(&WVAR_ENTRY(i), (char_u *)"w:"); | |
1453 for (i = 0; i < VV_LEN && !got_int; ++i) | 1514 for (i = 0; i < VV_LEN && !got_int; ++i) |
1454 if (vimvars[i].tv.v_type == VAR_NUMBER || vimvars[i].vv_str != NULL) | 1515 if (vimvars[i].tv.v_type == VAR_NUMBER || vimvars[i].vv_str != NULL) |
1455 list_vim_var(i); | 1516 list_vim_var(i); |
1456 } | 1517 } |
1457 | 1518 |
1516 { | 1577 { |
1517 c1 = *name_end; | 1578 c1 = *name_end; |
1518 *name_end = NUL; | 1579 *name_end = NUL; |
1519 arg_len = (int)(name_end - arg); | 1580 arg_len = (int)(name_end - arg); |
1520 } | 1581 } |
1521 i = find_vim_var(arg, arg_len); | 1582 if (arg_len == 2 && arg[1] == ':') |
1522 if (i >= 0) | |
1523 list_vim_var(i); | |
1524 else if (STRCMP("b:changedtick", arg) == 0) | |
1525 { | 1583 { |
1526 char_u numbuf[NUMBUFLEN]; | 1584 switch (*arg) |
1527 | 1585 { |
1528 sprintf((char *)numbuf, "%ld", | 1586 case 'g': list_glob_vars(); break; |
1529 (long)curbuf->b_changedtick); | 1587 case 'b': list_buf_vars(); break; |
1530 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", | 1588 case 'w': list_win_vars(); break; |
1531 VAR_NUMBER, numbuf); | 1589 case 'v': list_vim_vars(); break; |
1590 default: | |
1591 EMSG2(_("E738: Can't list variables for %s"), arg); | |
1592 } | |
1532 } | 1593 } |
1533 else | 1594 else |
1534 { | 1595 { |
1535 varp = find_var(arg, FALSE); | 1596 i = find_vim_var(arg, arg_len); |
1536 if (varp == NULL) | 1597 if (i >= 0) |
1598 list_vim_var(i); | |
1599 else if (STRCMP("b:changedtick", arg) == 0) | |
1537 { | 1600 { |
1538 /* Skip further arguments but do continue to | 1601 char_u numbuf[NUMBUFLEN]; |
1539 * search for a trailing command. */ | 1602 |
1540 EMSG2(_("E106: Unknown variable: \"%s\""), arg); | 1603 sprintf((char *)numbuf, "%ld", |
1541 error = TRUE; | 1604 (long)curbuf->b_changedtick); |
1605 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", | |
1606 VAR_NUMBER, numbuf); | |
1542 } | 1607 } |
1543 else | 1608 else |
1544 { | 1609 { |
1545 name = vim_strchr(arg, ':'); | 1610 varp = find_var(arg, NULL); |
1546 if (name != NULL) | 1611 if (varp == NULL) |
1547 { | 1612 { |
1548 /* "a:" vars have no name stored, use whole arg */ | 1613 /* Skip further arguments but do continue to |
1549 if (arg[0] == 'a' && arg[1] == ':') | 1614 * search for a trailing command. */ |
1550 c2 = NUL; | 1615 EMSG2(_("E106: Unknown variable: \"%s\""), arg); |
1551 else | 1616 error = TRUE; |
1552 { | |
1553 c2 = *++name; | |
1554 *name = NUL; | |
1555 } | |
1556 list_one_var(varp, arg); | |
1557 if (c2 != NUL) | |
1558 *name = c2; | |
1559 } | 1617 } |
1560 else | 1618 else |
1561 list_one_var(varp, (char_u *)""); | 1619 { |
1620 name = vim_strchr(arg, ':'); | |
1621 if (name != NULL) | |
1622 { | |
1623 /* "a:" vars have no name stored, use whole arg */ | |
1624 if (arg[0] == 'a' && arg[1] == ':') | |
1625 c2 = NUL; | |
1626 else | |
1627 { | |
1628 c2 = *++name; | |
1629 *name = NUL; | |
1630 } | |
1631 list_one_var(varp, arg); | |
1632 if (c2 != NUL) | |
1633 *name = c2; | |
1634 } | |
1635 else | |
1636 list_one_var(varp, (char_u *)""); | |
1637 } | |
1562 } | 1638 } |
1563 } | 1639 } |
1564 if (expr_start != NULL) | 1640 if (expr_start != NULL) |
1565 vim_free(temp_string); | 1641 vim_free(temp_string); |
1566 else | 1642 else |
1784 * If "rettv" is not NULL it points to the value to be assigned. | 1860 * If "rettv" is not NULL it points to the value to be assigned. |
1785 * "unlet" is TRUE for ":unlet": slightly different behavior when something is | 1861 * "unlet" is TRUE for ":unlet": slightly different behavior when something is |
1786 * wrong; must end in space or cmd separator. | 1862 * wrong; must end in space or cmd separator. |
1787 * | 1863 * |
1788 * Returns a pointer to just after the name, including indexes. | 1864 * Returns a pointer to just after the name, including indexes. |
1789 * When an evaluation error occurs "lp->name" is NULL; | 1865 * When an evaluation error occurs "lp->ll_name" is NULL; |
1790 * Returns NULL for a parsing error. Still need to free items in "lp"! | 1866 * Returns NULL for a parsing error. Still need to free items in "lp"! |
1791 */ | 1867 */ |
1792 static char_u * | 1868 static char_u * |
1793 get_lval(name, rettv, lp, unlet, skip, quiet) | 1869 get_lval(name, rettv, lp, unlet, skip, quiet) |
1794 char_u *name; | 1870 char_u *name; |
1806 typeval var2; | 1882 typeval var2; |
1807 int empty1 = FALSE; | 1883 int empty1 = FALSE; |
1808 listitem *ni; | 1884 listitem *ni; |
1809 char_u *key = NULL; | 1885 char_u *key = NULL; |
1810 int len; | 1886 int len; |
1887 hashtable *ht; | |
1811 | 1888 |
1812 /* Clear everything in "lp". */ | 1889 /* Clear everything in "lp". */ |
1813 vim_memset(lp, 0, sizeof(lval)); | 1890 vim_memset(lp, 0, sizeof(lval)); |
1814 | 1891 |
1815 if (skip) | 1892 if (skip) |
1853 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) | 1930 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) |
1854 return p; | 1931 return p; |
1855 | 1932 |
1856 cc = *p; | 1933 cc = *p; |
1857 *p = NUL; | 1934 *p = NUL; |
1858 v = find_var(lp->ll_name, TRUE); | 1935 v = find_var(lp->ll_name, &ht); |
1859 if (v == NULL && !quiet) | 1936 if (v == NULL && !quiet) |
1860 EMSG2(_(e_undefvar), lp->ll_name); | 1937 EMSG2(_(e_undefvar), lp->ll_name); |
1861 *p = cc; | 1938 *p = cc; |
1862 if (v == NULL) | 1939 if (v == NULL) |
1863 return NULL; | 1940 return NULL; |
2727 */ | 2804 */ |
2728 int | 2805 int |
2729 do_unlet(name) | 2806 do_unlet(name) |
2730 char_u *name; | 2807 char_u *name; |
2731 { | 2808 { |
2732 VAR v; | 2809 hashtable *ht; |
2733 | 2810 hashitem *hi; |
2734 v = find_var(name, TRUE); | 2811 char_u *varname; |
2735 if (v != NULL) | 2812 |
2736 { | 2813 if (name[0] == 'a' && name[1] == ':') |
2737 clear_var(v); | 2814 EMSG2(_(e_readonlyvar), name); |
2738 return OK; | 2815 else |
2816 { | |
2817 ht = find_var_ht(name, &varname); | |
2818 if (ht != NULL) | |
2819 { | |
2820 hi = hash_find(ht, varname); | |
2821 if (!HASHITEM_EMPTY(hi)) | |
2822 { | |
2823 delete_var(ht, hi); | |
2824 return OK; | |
2825 } | |
2826 } | |
2739 } | 2827 } |
2740 return FAIL; | 2828 return FAIL; |
2741 } | 2829 } |
2742 | 2830 |
2743 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) | 2831 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) |
2745 * Delete all "menutrans_" variables. | 2833 * Delete all "menutrans_" variables. |
2746 */ | 2834 */ |
2747 void | 2835 void |
2748 del_menutrans_vars() | 2836 del_menutrans_vars() |
2749 { | 2837 { |
2750 int i; | 2838 hashitem *hi; |
2751 | 2839 int todo; |
2752 for (i = 0; i < variables.ga_len; ++i) | 2840 |
2753 if (VAR_ENTRY(i).v_name != NULL | 2841 hash_lock(&variables); |
2754 && STRNCMP(VAR_ENTRY(i).v_name, "menutrans_", 10) == 0) | 2842 todo = variables.ht_used; |
2755 clear_var(&VAR_ENTRY(i)); | 2843 for (hi = variables.ht_array; todo > 0 && !got_int; ++hi) |
2844 { | |
2845 if (!HASHITEM_EMPTY(hi)) | |
2846 { | |
2847 --todo; | |
2848 if (STRNCMP(HI2VAR(hi)->v_name, "menutrans_", 10) == 0) | |
2849 delete_var(&variables, hi); | |
2850 } | |
2851 } | |
2852 hash_unlock(&variables); | |
2756 } | 2853 } |
2757 #endif | 2854 #endif |
2758 | 2855 |
2759 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) | 2856 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) |
2760 | 2857 |
2806 char_u * | 2903 char_u * |
2807 get_user_var_name(xp, idx) | 2904 get_user_var_name(xp, idx) |
2808 expand_T *xp; | 2905 expand_T *xp; |
2809 int idx; | 2906 int idx; |
2810 { | 2907 { |
2811 static int gidx; | 2908 static int gdone; |
2812 static int bidx; | 2909 static int bdone; |
2813 static int widx; | 2910 static int wdone; |
2814 static int vidx; | 2911 static int vidx; |
2815 char_u *name; | 2912 static hashitem *hi; |
2816 | 2913 |
2817 if (idx == 0) | 2914 if (idx == 0) |
2818 gidx = bidx = widx = vidx = 0; | 2915 gdone = bdone = wdone = vidx = 0; |
2819 if (gidx < variables.ga_len) /* Global variables */ | 2916 if (gdone < variables.ht_used) /* Global variables */ |
2820 { | 2917 { |
2821 while ((name = VAR_ENTRY(gidx++).v_name) == NULL | 2918 if (gdone++ == 0) |
2822 && gidx < variables.ga_len) | 2919 hi = variables.ht_array; |
2823 /* skip */; | 2920 while (HASHITEM_EMPTY(hi)) |
2824 if (name != NULL) | 2921 ++hi; |
2825 { | 2922 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) |
2826 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) | 2923 return cat_prefix_varname('g', hi->hi_key); |
2827 return cat_prefix_varname('g', name); | 2924 return hi->hi_key; |
2828 else | 2925 } |
2829 return name; | 2926 if (bdone < curbuf->b_vars.ht_used) /* Current buffer variables */ |
2830 } | 2927 { |
2831 } | 2928 if (bdone++ == 0) |
2832 if (bidx < curbuf->b_vars.ga_len) /* Current buffer variables */ | 2929 hi = curbuf->b_vars.ht_array; |
2833 { | 2930 while (HASHITEM_EMPTY(hi)) |
2834 while ((name = BVAR_ENTRY(bidx++).v_name) == NULL | 2931 ++hi; |
2835 && bidx < curbuf->b_vars.ga_len) | 2932 return cat_prefix_varname('b', hi->hi_key); |
2836 /* skip */; | 2933 } |
2837 if (name != NULL) | 2934 if (bdone == curbuf->b_vars.ht_used) |
2838 return cat_prefix_varname('b', name); | 2935 { |
2839 } | 2936 ++bdone; |
2840 if (bidx == curbuf->b_vars.ga_len) | |
2841 { | |
2842 ++bidx; | |
2843 return (char_u *)"b:changedtick"; | 2937 return (char_u *)"b:changedtick"; |
2844 } | 2938 } |
2845 if (widx < curwin->w_vars.ga_len) /* Current window variables */ | 2939 if (wdone < curwin->w_vars.ht_used) /* Current window variables */ |
2846 { | 2940 { |
2847 while ((name = WVAR_ENTRY(widx++).v_name) == NULL | 2941 if (bdone++ == 0) |
2848 && widx < curwin->w_vars.ga_len) | 2942 hi = curwin->w_vars.ht_array; |
2849 /* skip */; | 2943 while (HASHITEM_EMPTY(hi)) |
2850 if (name != NULL) | 2944 ++hi; |
2851 return cat_prefix_varname('w', name); | 2945 return cat_prefix_varname('w', hi->hi_key); |
2852 } | 2946 } |
2853 if (vidx < VV_LEN) /* Built-in variables */ | 2947 if (vidx < VV_LEN) /* Built-in variables */ |
2854 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].name); | 2948 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].name); |
2855 | 2949 |
2856 vim_free(varnamebuf); | 2950 vim_free(varnamebuf); |
3730 /* | 3824 /* |
3731 * Must be a variable or function name. | 3825 * Must be a variable or function name. |
3732 * Can also be a curly-braces kind of name: {expr}. | 3826 * Can also be a curly-braces kind of name: {expr}. |
3733 */ | 3827 */ |
3734 s = *arg; | 3828 s = *arg; |
3735 len = get_func_len(arg, &alias, evaluate); | 3829 len = get_name_len(arg, &alias, evaluate); |
3736 if (alias != NULL) | 3830 if (alias != NULL) |
3737 s = alias; | 3831 s = alias; |
3738 | 3832 |
3739 if (len == 0) | 3833 if (len == 0) |
3740 ret = FAIL; | 3834 ret = FAIL; |
5008 { | 5102 { |
5009 dictitem_free(HI2DI(hi)); | 5103 dictitem_free(HI2DI(hi)); |
5010 --todo; | 5104 --todo; |
5011 } | 5105 } |
5012 } | 5106 } |
5107 hash_clear(&d->dv_hashtable); | |
5013 vim_free(d); | 5108 vim_free(d); |
5014 } | 5109 } |
5015 | 5110 |
5016 /* | 5111 /* |
5017 * Allocate a Dictionary item. | 5112 * Allocate a Dictionary item. |
5821 VAR v; | 5916 VAR v; |
5822 int cc; | 5917 int cc; |
5823 | 5918 |
5824 cc = name[*lenp]; | 5919 cc = name[*lenp]; |
5825 name[*lenp] = NUL; | 5920 name[*lenp] = NUL; |
5826 v = find_var(name, FALSE); | 5921 v = find_var(name, NULL); |
5827 name[*lenp] = cc; | 5922 name[*lenp] = cc; |
5828 if (v != NULL && v->tv.v_type == VAR_FUNC) | 5923 if (v != NULL && v->tv.v_type == VAR_FUNC) |
5829 { | 5924 { |
5830 if (v->tv.vval.v_string == NULL) | 5925 if (v->tv.vval.v_string == NULL) |
5831 { | 5926 { |
6703 if (argvars[2].v_type != VAR_UNKNOWN) | 6798 if (argvars[2].v_type != VAR_UNKNOWN) |
6704 { | 6799 { |
6705 def = get_tv_number(&argvars[2]); | 6800 def = get_tv_number(&argvars[2]); |
6706 if (argvars[3].v_type != VAR_UNKNOWN) | 6801 if (argvars[3].v_type != VAR_UNKNOWN) |
6707 { | 6802 { |
6708 /* avoid that TOUPPER_ASC calls get_var_string_buf() twice */ | 6803 /* avoid that TOUPPER_ASC calls get_tv_string_buf() twice */ |
6709 c = *get_tv_string_buf(&argvars[3], buf2); | 6804 c = *get_tv_string_buf(&argvars[3], buf2); |
6710 switch (TOUPPER_ASC(c)) | 6805 switch (TOUPPER_ASC(c)) |
6711 { | 6806 { |
6712 case 'E': type = VIM_ERROR; break; | 6807 case 'E': type = VIM_ERROR; break; |
6713 case 'Q': type = VIM_QUESTION; break; | 6808 case 'Q': type = VIM_QUESTION; break; |
7427 char_u buf[NUMBUFLEN]; | 7522 char_u buf[NUMBUFLEN]; |
7428 char_u *expr; | 7523 char_u *expr; |
7429 listitem *li, *nli; | 7524 listitem *li, *nli; |
7430 listvar *l = NULL; | 7525 listvar *l = NULL; |
7431 dictitem *di; | 7526 dictitem *di; |
7527 hashtable *ht; | |
7432 hashitem *hi; | 7528 hashitem *hi; |
7433 dictvar *d = NULL; | 7529 dictvar *d = NULL; |
7434 typeval save_val; | 7530 typeval save_val; |
7435 typeval save_key; | 7531 typeval save_key; |
7436 int rem; | 7532 int rem; |
7459 if (argvars[0].v_type == VAR_DICT) | 7555 if (argvars[0].v_type == VAR_DICT) |
7460 { | 7556 { |
7461 save_key = vimvars[VV_KEY].tv; | 7557 save_key = vimvars[VV_KEY].tv; |
7462 vimvars[VV_KEY].tv.v_type = VAR_STRING; | 7558 vimvars[VV_KEY].tv.v_type = VAR_STRING; |
7463 | 7559 |
7464 todo = d->dv_hashtable.ht_used; | 7560 ht = &d->dv_hashtable; |
7465 for (hi = d->dv_hashtable.ht_array; todo > 0; ++hi) | 7561 hash_lock(ht); |
7562 todo = ht->ht_used; | |
7563 for (hi = ht->ht_array; todo > 0; ++hi) | |
7466 { | 7564 { |
7467 if (!HASHITEM_EMPTY(hi)) | 7565 if (!HASHITEM_EMPTY(hi)) |
7468 { | 7566 { |
7469 --todo; | 7567 --todo; |
7470 di = HI2DI(hi); | 7568 di = HI2DI(hi); |
7474 if (!map && rem) | 7572 if (!map && rem) |
7475 dictitem_remove(d, di); | 7573 dictitem_remove(d, di); |
7476 clear_tv(&vimvars[VV_KEY].tv); | 7574 clear_tv(&vimvars[VV_KEY].tv); |
7477 } | 7575 } |
7478 } | 7576 } |
7577 hash_unlock(ht); | |
7479 | 7578 |
7480 clear_tv(&vimvars[VV_KEY].tv); | 7579 clear_tv(&vimvars[VV_KEY].tv); |
7481 vimvars[VV_KEY].tv = save_key; | 7580 vimvars[VV_KEY].tv = save_key; |
7482 } | 7581 } |
7483 else | 7582 else |
7797 typeval *argvars; | 7896 typeval *argvars; |
7798 typeval *rettv; | 7897 typeval *rettv; |
7799 { | 7898 { |
7800 char_u *s; | 7899 char_u *s; |
7801 | 7900 |
7901 rettv->vval.v_number = 0; | |
7802 s = get_tv_string(&argvars[0]); | 7902 s = get_tv_string(&argvars[0]); |
7803 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) | 7903 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) |
7804 EMSG2(_(e_invarg2), s); | 7904 EMSG2(_(e_invarg2), s); |
7805 else if (!function_exists(s)) | 7905 else if (!function_exists(s)) |
7806 EMSG2(_("E700: Unknown function: %s"), s); | 7906 EMSG2(_("E700: Unknown function: %s"), s); |
7891 curbuf = save_curbuf; | 7991 curbuf = save_curbuf; |
7892 } | 7992 } |
7893 else | 7993 else |
7894 { | 7994 { |
7895 /* look up the variable */ | 7995 /* look up the variable */ |
7896 v = find_var_in_ga(&buf->b_vars, varname); | 7996 v = find_var_in_ht(&buf->b_vars, varname); |
7897 if (v != NULL) | 7997 if (v != NULL) |
7898 copy_tv(&v->tv, rettv); | 7998 copy_tv(&v->tv, rettv); |
7899 } | 7999 } |
7900 } | 8000 } |
7901 | 8001 |
8415 curwin = oldcurwin; | 8515 curwin = oldcurwin; |
8416 } | 8516 } |
8417 else | 8517 else |
8418 { | 8518 { |
8419 /* look up the variable */ | 8519 /* look up the variable */ |
8420 v = find_var_in_ga(&win->w_vars, varname); | 8520 v = find_var_in_ht(&win->w_vars, varname); |
8421 if (v != NULL) | 8521 if (v != NULL) |
8422 copy_tv(&v->tv, rettv); | 8522 copy_tv(&v->tv, rettv); |
8423 } | 8523 } |
8424 } | 8524 } |
8425 | 8525 |
12715 | 12815 |
12716 return len; | 12816 return len; |
12717 } | 12817 } |
12718 | 12818 |
12719 /* | 12819 /* |
12720 * Get the length of the name of a function. | 12820 * Get the length of the name of a variable or function. |
12821 * Only the name is recognized, does not handle ".key" or "[idx]". | |
12721 * "arg" is advanced to the first non-white character after the name. | 12822 * "arg" is advanced to the first non-white character after the name. |
12722 * Return 0 if something is wrong. | 12823 * Return 0 if something is wrong. |
12723 * If the name contains 'magic' {}'s, expand them and return the | 12824 * If the name contains 'magic' {}'s, expand them and return the |
12724 * expanded name in an allocated string via 'alias' - caller must free. | 12825 * expanded name in an allocated string via 'alias' - caller must free. |
12725 */ | 12826 */ |
12726 static int | 12827 static int |
12727 get_func_len(arg, alias, evaluate) | 12828 get_name_len(arg, alias, evaluate) |
12728 char_u **arg; | 12829 char_u **arg; |
12729 char_u **alias; | 12830 char_u **alias; |
12730 int evaluate; | 12831 int evaluate; |
12731 { | 12832 { |
12732 int len; | 12833 int len; |
13087 | 13188 |
13088 /* | 13189 /* |
13089 * Check for built-in v: variables. | 13190 * Check for built-in v: variables. |
13090 */ | 13191 */ |
13091 else if ((i = find_vim_var(name, len)) >= 0) | 13192 else if ((i = find_vim_var(name, len)) >= 0) |
13092 { | |
13093 tv = &vimvars[i].tv; | 13193 tv = &vimvars[i].tv; |
13094 } | |
13095 | 13194 |
13096 /* | 13195 /* |
13097 * Check for user-defined variables. | 13196 * Check for user-defined variables. |
13098 */ | 13197 */ |
13099 else | 13198 else |
13100 { | 13199 { |
13101 v = find_var(name, FALSE); | 13200 v = find_var(name, NULL); |
13102 if (v != NULL) | 13201 if (v != NULL) |
13103 tv = &v->tv; | 13202 tv = &v->tv; |
13104 } | 13203 } |
13105 | 13204 |
13106 if (tv == NULL) | 13205 if (tv == NULL) |
13285 } | 13384 } |
13286 | 13385 |
13287 /* | 13386 /* |
13288 * Get the string value of a variable. | 13387 * Get the string value of a variable. |
13289 * If it is a Number variable, the number is converted into a string. | 13388 * If it is a Number variable, the number is converted into a string. |
13290 * get_var_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! | 13389 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! |
13291 * get_var_string_buf() uses a given buffer. | 13390 * get_tv_string_buf() uses a given buffer. |
13292 * If the String variable has never been set, return an empty string. | 13391 * If the String variable has never been set, return an empty string. |
13293 * Never returns NULL; | 13392 * Never returns NULL; |
13294 */ | 13393 */ |
13295 static char_u * | 13394 static char_u * |
13296 get_tv_string(varp) | 13395 get_tv_string(varp) |
13333 | 13432 |
13334 /* | 13433 /* |
13335 * Find variable "name" in the list of variables. | 13434 * Find variable "name" in the list of variables. |
13336 * Return a pointer to it if found, NULL if not found. | 13435 * Return a pointer to it if found, NULL if not found. |
13337 * Careful: "a:0" variables don't have a name. | 13436 * Careful: "a:0" variables don't have a name. |
13437 * When "htp" is not NULL we are writing to the variable, set "htp" to the | |
13438 * hashtable used. | |
13338 */ | 13439 */ |
13339 static VAR | 13440 static VAR |
13340 find_var(name, writing) | 13441 find_var(name, htp) |
13341 char_u *name; | 13442 char_u *name; |
13342 int writing; | 13443 hashtable **htp; |
13343 { | 13444 { |
13344 int i; | 13445 int i; |
13345 char_u *varname; | 13446 char_u *varname; |
13346 garray_T *gap; | 13447 hashtable *ht; |
13347 | 13448 |
13348 if (name[0] == 'a' && name[1] == ':') | 13449 if (name[0] == 'a' && name[1] == ':') |
13349 { | 13450 { |
13350 /* Function arguments "a:". | 13451 /* Function arguments "a:". |
13351 * NOTE: We use a typecast, because function arguments don't have a | 13452 * NOTE: We use a typecast, because function arguments don't have a |
13352 * name. The caller must not try to access the name! */ | 13453 * name. The caller must not try to access the name! */ |
13353 if (writing) | 13454 if (htp != NULL) |
13354 { | 13455 { |
13355 EMSG2(_(e_readonlyvar), name); | 13456 EMSG2(_(e_readonlyvar), name); |
13356 return NULL; | 13457 return NULL; |
13357 } | 13458 } |
13358 name += 2; | 13459 name += 2; |
13377 (current_funccal->func->args.ga_data))[i]) == 0) | 13478 (current_funccal->func->args.ga_data))[i]) == 0) |
13378 return (VAR)&(current_funccal->argvars[i]); /* a:name */ | 13479 return (VAR)&(current_funccal->argvars[i]); /* a:name */ |
13379 return NULL; | 13480 return NULL; |
13380 } | 13481 } |
13381 | 13482 |
13382 gap = find_var_ga(name, &varname); | 13483 ht = find_var_ht(name, &varname); |
13383 if (gap == NULL) | 13484 if (htp != NULL) |
13485 *htp = ht; | |
13486 if (ht == NULL) | |
13384 return NULL; | 13487 return NULL; |
13385 return find_var_in_ga(gap, varname); | 13488 return find_var_in_ht(ht, varname); |
13386 } | 13489 } |
13387 | 13490 |
13491 /* | |
13492 * Find variable "varname" in hashtable "ht". | |
13493 * Returns NULL if not found. | |
13494 */ | |
13388 static VAR | 13495 static VAR |
13389 find_var_in_ga(gap, varname) | 13496 find_var_in_ht(ht, varname) |
13390 garray_T *gap; | 13497 hashtable *ht; |
13391 char_u *varname; | 13498 char_u *varname; |
13392 { | 13499 { |
13393 int i; | 13500 hashitem *hi; |
13394 | 13501 |
13395 for (i = gap->ga_len; --i >= 0; ) | 13502 hi = hash_find(ht, varname); |
13396 if (VAR_GAP_ENTRY(i, gap).v_name != NULL | 13503 if (HASHITEM_EMPTY(hi)) |
13397 && STRCMP(VAR_GAP_ENTRY(i, gap).v_name, varname) == 0) | |
13398 break; | |
13399 if (i < 0) | |
13400 return NULL; | 13504 return NULL; |
13401 return &VAR_GAP_ENTRY(i, gap); | 13505 return HI2VAR(hi); |
13402 } | 13506 } |
13403 | 13507 |
13404 /* | 13508 /* |
13405 * Find the growarray and start of name without ':' for a variable name. | 13509 * Find the hashtable used for a variable name. |
13406 */ | 13510 * Set "varname" to the start of name without ':'. |
13407 static garray_T * | 13511 */ |
13408 find_var_ga(name, varname) | 13512 static hashtable * |
13513 find_var_ht(name, varname) | |
13409 char_u *name; | 13514 char_u *name; |
13410 char_u **varname; | 13515 char_u **varname; |
13411 { | 13516 { |
13412 if (name[1] != ':') | 13517 if (name[1] != ':') |
13413 { | 13518 { |
13442 get_var_value(name) | 13547 get_var_value(name) |
13443 char_u *name; | 13548 char_u *name; |
13444 { | 13549 { |
13445 VAR v; | 13550 VAR v; |
13446 | 13551 |
13447 v = find_var(name, FALSE); | 13552 v = find_var(name, NULL); |
13448 if (v == NULL) | 13553 if (v == NULL) |
13449 return NULL; | 13554 return NULL; |
13450 return get_var_string(v); | 13555 return get_tv_string(&v->tv); |
13451 } | 13556 } |
13452 | 13557 |
13453 /* | 13558 /* |
13454 * Allocate a new growarry for a sourced script. It will be used while | 13559 * Allocate a new hashtable for a sourced script. It will be used while |
13455 * sourcing this script and when executing functions defined in the script. | 13560 * sourcing this script and when executing functions defined in the script. |
13456 */ | 13561 */ |
13457 void | 13562 void |
13458 new_script_vars(id) | 13563 new_script_vars(id) |
13459 scid_T id; | 13564 scid_T id; |
13460 { | 13565 { |
13566 int i; | |
13567 hashtable *ht; | |
13568 | |
13461 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) | 13569 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) |
13462 { | 13570 { |
13571 /* Re-allocating ga_data means that an ht_array pointing to | |
13572 * ht_smallarray becomes invalid. We can recognize this: ht_mask is | |
13573 * at its init value. */ | |
13574 for (i = 1; i <= ga_scripts.ga_len; ++i) | |
13575 { | |
13576 ht = &SCRIPT_VARS(i); | |
13577 if (ht->ht_mask == HT_INIT_SIZE - 1) | |
13578 ht->ht_array = ht->ht_smallarray; | |
13579 } | |
13580 | |
13463 while (ga_scripts.ga_len < id) | 13581 while (ga_scripts.ga_len < id) |
13464 { | 13582 { |
13465 vars_init(&SCRIPT_VARS(ga_scripts.ga_len + 1)); | 13583 vars_init(&SCRIPT_VARS(ga_scripts.ga_len + 1)); |
13466 ++ga_scripts.ga_len; | 13584 ++ga_scripts.ga_len; |
13467 } | 13585 } |
13468 } | 13586 } |
13469 } | 13587 } |
13470 | 13588 |
13471 /* | 13589 /* |
13472 * Initialize internal variables for use. | 13590 * Initialize hashtable with variables for use. |
13473 */ | 13591 */ |
13474 void | 13592 void |
13475 vars_init(gap) | 13593 vars_init(ht) |
13476 garray_T *gap; | 13594 hashtable *ht; |
13477 { | 13595 { |
13478 ga_init2(gap, (int)sizeof(var), 4); | 13596 hash_init(ht); |
13479 } | 13597 } |
13480 | 13598 |
13481 /* | 13599 /* |
13482 * Clean up a list of internal variables. | 13600 * Clean up a list of internal variables. |
13483 */ | 13601 */ |
13484 void | 13602 void |
13485 vars_clear(gap) | 13603 vars_clear(ht) |
13486 garray_T *gap; | 13604 hashtable *ht; |
13487 { | 13605 { |
13488 int i; | 13606 int todo; |
13489 | 13607 hashitem *hi; |
13490 for (i = gap->ga_len; --i >= 0; ) | 13608 VAR v; |
13491 clear_var(&VAR_GAP_ENTRY(i, gap)); | 13609 |
13492 ga_clear(gap); | 13610 todo = ht->ht_used; |
13493 } | 13611 for (hi = ht->ht_array; todo > 0; ++hi) |
13494 | 13612 { |
13495 static void | 13613 if (!HASHITEM_EMPTY(hi)) |
13496 clear_var(v) | 13614 { |
13497 VAR v; | 13615 --todo; |
13498 { | 13616 |
13499 vim_free(v->v_name); | 13617 /* Free the variable. Don't remove it from the hashtable, |
13500 v->v_name = NULL; | 13618 * ht_array might change then. hash_clear() takes care of it |
13619 * later. */ | |
13620 v = HI2VAR(hi); | |
13621 clear_tv(&v->tv); | |
13622 vim_free(v); | |
13623 } | |
13624 } | |
13625 hash_clear(ht); | |
13626 hash_init(ht); | |
13627 } | |
13628 | |
13629 /* | |
13630 * Delete a variable from hashtable "ht" at item "hi". | |
13631 */ | |
13632 static void | |
13633 delete_var(ht, hi) | |
13634 hashtable *ht; | |
13635 hashitem *hi; | |
13636 { | |
13637 VAR v = HI2VAR(hi); | |
13638 | |
13639 hash_remove(ht, hi); | |
13501 clear_tv(&v->tv); | 13640 clear_tv(&v->tv); |
13641 vim_free(v); | |
13502 } | 13642 } |
13503 | 13643 |
13504 /* | 13644 /* |
13505 * List the value of one internal variable. | 13645 * List the value of one internal variable. |
13506 */ | 13646 */ |
13585 int copy; /* make copy of value in "tv" */ | 13725 int copy; /* make copy of value in "tv" */ |
13586 { | 13726 { |
13587 int i; | 13727 int i; |
13588 VAR v; | 13728 VAR v; |
13589 char_u *varname; | 13729 char_u *varname; |
13590 garray_T *gap; | 13730 hashtable *ht; |
13591 | 13731 |
13592 /* | 13732 /* |
13593 * Handle setting internal v: variables. | 13733 * Handle setting internal v: variables. |
13594 */ | 13734 */ |
13595 i = find_vim_var(name, (int)STRLEN(name)); | 13735 i = find_vim_var(name, (int)STRLEN(name)); |
13633 EMSG2(_("705: Variable name conflicts with existing function: %s"), name); | 13773 EMSG2(_("705: Variable name conflicts with existing function: %s"), name); |
13634 return; | 13774 return; |
13635 } | 13775 } |
13636 } | 13776 } |
13637 | 13777 |
13638 v = find_var(name, TRUE); | 13778 if (name[0] == 'a' && name[1] == ':') |
13639 if (v != NULL) /* existing variable, only need to free string */ | 13779 { |
13780 EMSG2(_(e_readonlyvar), name); | |
13781 return; | |
13782 } | |
13783 | |
13784 ht = find_var_ht(name, &varname); | |
13785 if (ht == NULL) | |
13786 { | |
13787 EMSG2(_("E461: Illegal variable name: %s"), name); | |
13788 return; | |
13789 } | |
13790 | |
13791 v = find_var_in_ht(ht, varname); | |
13792 if (v != NULL) /* existing variable, need to clear the value */ | |
13640 { | 13793 { |
13641 if (v->tv.v_type != tv->v_type | 13794 if (v->tv.v_type != tv->v_type |
13642 && !((v->tv.v_type == VAR_STRING | 13795 && !((v->tv.v_type == VAR_STRING |
13643 || v->tv.v_type == VAR_NUMBER) | 13796 || v->tv.v_type == VAR_NUMBER) |
13644 && (tv->v_type == VAR_STRING | 13797 && (tv->v_type == VAR_STRING |
13649 } | 13802 } |
13650 clear_tv(&v->tv); | 13803 clear_tv(&v->tv); |
13651 } | 13804 } |
13652 else /* add a new variable */ | 13805 else /* add a new variable */ |
13653 { | 13806 { |
13654 gap = find_var_ga(name, &varname); | 13807 v = (VAR)alloc((unsigned)(sizeof(var) + STRLEN(varname))); |
13655 if (gap == NULL) /* illegal name */ | 13808 if (v == NULL) |
13656 { | |
13657 EMSG2(_("E461: Illegal variable name: %s"), name); | |
13658 return; | 13809 return; |
13659 } | 13810 STRCPY(v->v_name, varname); |
13660 | 13811 if (hash_add(ht, VAR2HIKEY(v)) == FAIL) |
13661 /* Try to use an empty entry */ | 13812 { |
13662 for (i = gap->ga_len; --i >= 0; ) | 13813 vim_free(v); |
13663 if (VAR_GAP_ENTRY(i, gap).v_name == NULL) | |
13664 break; | |
13665 if (i < 0) /* need to allocate more room */ | |
13666 { | |
13667 if (ga_grow(gap, 1) == FAIL) | |
13668 return; | |
13669 i = gap->ga_len; | |
13670 } | |
13671 v = &VAR_GAP_ENTRY(i, gap); | |
13672 if ((v->v_name = vim_strsave(varname)) == NULL) | |
13673 return; | 13814 return; |
13674 if (i == gap->ga_len) | 13815 } |
13675 ++gap->ga_len; | 13816 } |
13676 } | 13817 |
13677 if (copy || tv->v_type == VAR_NUMBER) | 13818 if (copy || tv->v_type == VAR_NUMBER) |
13678 copy_tv(tv, &v->tv); | 13819 copy_tv(tv, &v->tv); |
13679 else | 13820 else |
13680 { | 13821 { |
13681 v->tv = *tv; | 13822 v->tv = *tv; |
14356 /* | 14497 /* |
14357 * If there are no errors, add the function | 14498 * If there are no errors, add the function |
14358 */ | 14499 */ |
14359 if (fudi.fd_dict == NULL) | 14500 if (fudi.fd_dict == NULL) |
14360 { | 14501 { |
14361 v = find_var(name, FALSE); | 14502 v = find_var(name, NULL); |
14362 if (v != NULL && v->tv.v_type == VAR_FUNC) | 14503 if (v != NULL && v->tv.v_type == VAR_FUNC) |
14363 { | 14504 { |
14364 EMSG2(_("E707: Function name conflicts with variable: %s"), name); | 14505 EMSG2(_("E707: Function name conflicts with variable: %s"), name); |
14365 goto erret; | 14506 goto erret; |
14366 } | 14507 } |
14461 did_emsg |= saved_did_emsg; | 14602 did_emsg |= saved_did_emsg; |
14462 } | 14603 } |
14463 | 14604 |
14464 /* | 14605 /* |
14465 * Get a function name, translating "<SID>" and "<SNR>". | 14606 * Get a function name, translating "<SID>" and "<SNR>". |
14607 * Also handles a Funcref in a List or Dictionary. | |
14466 * Returns the function name in allocated memory, or NULL for failure. | 14608 * Returns the function name in allocated memory, or NULL for failure. |
14467 * flags: | 14609 * flags: |
14468 * TFN_INT: internal function name OK | 14610 * TFN_INT: internal function name OK |
14469 * TFN_QUIET: be quiet | 14611 * TFN_QUIET: be quiet |
14470 * Advances "pp" to just after the function name (if no error). | 14612 * Advances "pp" to just after the function name (if no error). |
14484 int len; | 14626 int len; |
14485 lval lv; | 14627 lval lv; |
14486 | 14628 |
14487 if (fdp != NULL) | 14629 if (fdp != NULL) |
14488 vim_memset(fdp, 0, sizeof(funcdict)); | 14630 vim_memset(fdp, 0, sizeof(funcdict)); |
14489 | |
14490 /* A name starting with "<SID>" or "<SNR>" is local to a script. */ | |
14491 start = *pp; | 14631 start = *pp; |
14632 | |
14633 /* Check for hard coded <SNR>: already translated function ID (from a user | |
14634 * command). */ | |
14635 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA | |
14636 && (*pp)[2] == (int)KE_SNR) | |
14637 { | |
14638 *pp += 3; | |
14639 len = get_id_len(pp) + 3; | |
14640 return vim_strnsave(start, len); | |
14641 } | |
14642 | |
14643 /* A name starting with "<SID>" or "<SNR>" is local to a script. But | |
14644 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ | |
14492 lead = eval_fname_script(start); | 14645 lead = eval_fname_script(start); |
14493 if (lead > 0) | 14646 if (lead > 2) |
14494 start += lead; | 14647 start += lead; |
14495 | 14648 |
14496 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET); | 14649 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET); |
14497 if (end == start) | 14650 if (end == start) |
14498 { | 14651 { |
14499 if (!skip) | 14652 if (!skip) |
14500 EMSG(_("E129: Function name required")); | 14653 EMSG(_("E129: Function name required")); |
14501 goto theend; | 14654 goto theend; |
14502 } | 14655 } |
14503 if (end == NULL || (lv.ll_tv != NULL && (lead > 0 || lv.ll_range))) | 14656 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) |
14504 { | 14657 { |
14505 /* | 14658 /* |
14506 * Report an invalid expression in braces, unless the expression | 14659 * Report an invalid expression in braces, unless the expression |
14507 * evaluation has been cancelled due to an aborting error, an | 14660 * evaluation has been cancelled due to an aborting error, an |
14508 * interrupt, or an exception. | 14661 * interrupt, or an exception. |
14551 } | 14704 } |
14552 | 14705 |
14553 if (lv.ll_exp_name != NULL) | 14706 if (lv.ll_exp_name != NULL) |
14554 len = STRLEN(lv.ll_exp_name); | 14707 len = STRLEN(lv.ll_exp_name); |
14555 else | 14708 else |
14556 len = (int)(end - start); | 14709 { |
14710 if (lead == 2) /* skip over "s:" */ | |
14711 lv.ll_name += 2; | |
14712 len = (int)(end - lv.ll_name); | |
14713 } | |
14557 | 14714 |
14558 /* | 14715 /* |
14559 * Copy the function name to allocated memory. | 14716 * Copy the function name to allocated memory. |
14560 * Accept <SID>name() inside a script, translate into <SNR>123_name(). | 14717 * Accept <SID>name() inside a script, translate into <SNR>123_name(). |
14561 * Accept <SNR>123_name() outside a script. | 14718 * Accept <SNR>123_name() outside a script. |
14588 if (lead > 0) | 14745 if (lead > 0) |
14589 { | 14746 { |
14590 name[0] = K_SPECIAL; | 14747 name[0] = K_SPECIAL; |
14591 name[1] = KS_EXTRA; | 14748 name[1] = KS_EXTRA; |
14592 name[2] = (int)KE_SNR; | 14749 name[2] = (int)KE_SNR; |
14593 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ | 14750 if (lead > 3) /* If it's "<SID>" */ |
14594 STRCPY(name + 3, sid_buf); | 14751 STRCPY(name + 3, sid_buf); |
14595 } | 14752 } |
14596 mch_memmove(name + lead, lv.ll_name, (size_t)len); | 14753 mch_memmove(name + lead, lv.ll_name, (size_t)len); |
14597 name[len + lead] = NUL; | 14754 name[len + lead] = NUL; |
14598 } | 14755 } |
14936 fc.linenr = 0; | 15093 fc.linenr = 0; |
14937 fc.returned = FALSE; | 15094 fc.returned = FALSE; |
14938 fc.level = ex_nesting_level; | 15095 fc.level = ex_nesting_level; |
14939 fc.a0_var.tv.v_type = VAR_NUMBER; | 15096 fc.a0_var.tv.v_type = VAR_NUMBER; |
14940 fc.a0_var.tv.vval.v_number = argcount - fp->args.ga_len; | 15097 fc.a0_var.tv.vval.v_number = argcount - fp->args.ga_len; |
14941 fc.a0_var.v_name = NULL; | 15098 fc.a0_var.v_name[0] = NUL; |
14942 current_funccal = &fc; | 15099 current_funccal = &fc; |
14943 fc.firstline.tv.v_type = VAR_NUMBER; | 15100 fc.firstline.tv.v_type = VAR_NUMBER; |
14944 fc.firstline.tv.vval.v_number = firstline; | 15101 fc.firstline.tv.vval.v_number = firstline; |
14945 fc.firstline.v_name = NULL; | 15102 fc.firstline.v_name[0] = NUL; |
14946 fc.lastline.tv.v_type = VAR_NUMBER; | 15103 fc.lastline.tv.v_type = VAR_NUMBER; |
14947 fc.lastline.tv.vval.v_number = lastline; | 15104 fc.lastline.tv.vval.v_number = lastline; |
14948 fc.lastline.v_name = NULL; | 15105 fc.lastline.v_name[0] = NUL; |
14949 /* Check if this function has a breakpoint. */ | 15106 /* Check if this function has a breakpoint. */ |
14950 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0); | 15107 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0); |
14951 fc.dbg_tick = debug_tick; | 15108 fc.dbg_tick = debug_tick; |
14952 | 15109 |
14953 if (selfdict != NULL && ga_grow(&fc.l_vars, 1) != FAIL) | 15110 if (selfdict != NULL) |
14954 { | 15111 { |
14955 VAR v = &VAR_GAP_ENTRY(0, &fc.l_vars); | 15112 VAR v = (VAR)alloc((unsigned)(sizeof(var) + 4)); |
14956 | 15113 |
14957 /* Set the "self" local variable. */ | 15114 if (v != NULL) |
14958 if ((v->v_name = vim_strsave((char_u *)"self")) != NULL) | 15115 { |
14959 { | 15116 STRCPY(v->v_name, "self"); |
14960 ++fc.l_vars.ga_len; | 15117 hash_add(&fc.l_vars, VAR2HIKEY(v)); |
14961 v->tv.v_type = VAR_DICT; | 15118 v->tv.v_type = VAR_DICT; |
14962 v->tv.vval.v_dict = selfdict; | 15119 v->tv.vval.v_dict = selfdict; |
14963 ++selfdict->dv_refcount; | 15120 ++selfdict->dv_refcount; |
14964 } | 15121 } |
14965 } | 15122 } |
15410 */ | 15567 */ |
15411 void | 15568 void |
15412 write_viminfo_varlist(fp) | 15569 write_viminfo_varlist(fp) |
15413 FILE *fp; | 15570 FILE *fp; |
15414 { | 15571 { |
15415 garray_T *gap = &variables; /* global variable */ | 15572 hashitem *hi; |
15416 VAR this_var; | 15573 VAR this_var; |
15417 int i; | 15574 int todo; |
15418 char *s; | 15575 char *s; |
15419 char_u *tofree; | 15576 char_u *tofree; |
15420 char_u numbuf[NUMBUFLEN]; | 15577 char_u numbuf[NUMBUFLEN]; |
15421 | 15578 |
15422 if (find_viminfo_parameter('!') == NULL) | 15579 if (find_viminfo_parameter('!') == NULL) |
15423 return; | 15580 return; |
15424 | 15581 |
15425 fprintf(fp, _("\n# global variables:\n")); | 15582 fprintf(fp, _("\n# global variables:\n")); |
15426 for (i = gap->ga_len; --i >= 0; ) | 15583 |
15427 { | 15584 todo = variables.ht_used; |
15428 this_var = &VAR_GAP_ENTRY(i, gap); | 15585 for (hi = variables.ht_array; todo > 0; ++hi) |
15429 if (this_var->v_name != NULL | 15586 { |
15430 && var_flavour(this_var->v_name) == VAR_FLAVOUR_VIMINFO) | 15587 if (!HASHITEM_EMPTY(hi)) |
15431 { | 15588 { |
15432 switch (this_var->tv.v_type) | 15589 --todo; |
15590 this_var = HI2VAR(hi); | |
15591 if (var_flavour(this_var->v_name) == VAR_FLAVOUR_VIMINFO) | |
15433 { | 15592 { |
15434 case VAR_STRING: s = "STR"; break; | 15593 switch (this_var->tv.v_type) |
15435 case VAR_NUMBER: s = "NUM"; break; | 15594 { |
15436 default: continue; | 15595 case VAR_STRING: s = "STR"; break; |
15596 case VAR_NUMBER: s = "NUM"; break; | |
15597 default: continue; | |
15598 } | |
15599 fprintf(fp, "!%s\t%s\t", this_var->v_name, s); | |
15600 viminfo_writestring(fp, echo_string(&this_var->tv, | |
15601 &tofree, numbuf)); | |
15602 vim_free(tofree); | |
15437 } | 15603 } |
15438 fprintf(fp, "!%s\t%s\t", this_var->v_name, s); | |
15439 viminfo_writestring(fp, echo_string(&this_var->tv, | |
15440 &tofree, numbuf)); | |
15441 vim_free(tofree); | |
15442 } | 15604 } |
15443 } | 15605 } |
15444 } | 15606 } |
15445 #endif | 15607 #endif |
15446 | 15608 |
15447 #if defined(FEAT_SESSION) || defined(PROTO) | 15609 #if defined(FEAT_SESSION) || defined(PROTO) |
15448 int | 15610 int |
15449 store_session_globals(fd) | 15611 store_session_globals(fd) |
15450 FILE *fd; | 15612 FILE *fd; |
15451 { | 15613 { |
15452 garray_T *gap = &variables; /* global variable */ | 15614 hashitem *hi; |
15453 VAR this_var; | 15615 VAR this_var; |
15454 int i; | 15616 int todo; |
15455 char_u *p, *t; | 15617 char_u *p, *t; |
15456 | 15618 |
15457 for (i = gap->ga_len; --i >= 0; ) | 15619 todo = variables.ht_used; |
15458 { | 15620 for (hi = variables.ht_array; todo > 0; ++hi) |
15459 this_var = &VAR_GAP_ENTRY(i, gap); | 15621 { |
15460 if (this_var->v_name != NULL | 15622 if (!HASHITEM_EMPTY(hi)) |
15461 && (this_var->tv.v_type == VAR_NUMBER | 15623 { |
15462 || this_var->tv.v_type == VAR_STRING) | 15624 --todo; |
15463 && var_flavour(this_var->v_name) == VAR_FLAVOUR_SESSION) | 15625 this_var = HI2VAR(hi); |
15464 { | 15626 if ((this_var->tv.v_type == VAR_NUMBER |
15465 /* Escape special characters with a backslash. Turn a LF and | 15627 || this_var->tv.v_type == VAR_STRING) |
15466 * CR into \n and \r. */ | 15628 && var_flavour(this_var->v_name) == VAR_FLAVOUR_SESSION) |
15467 p = vim_strsave_escaped(get_var_string(this_var), | 15629 { |
15630 /* Escape special characters with a backslash. Turn a LF and | |
15631 * CR into \n and \r. */ | |
15632 p = vim_strsave_escaped(get_tv_string(&this_var->tv), | |
15468 (char_u *)"\\\"\n\r"); | 15633 (char_u *)"\\\"\n\r"); |
15469 if (p == NULL) /* out of memory */ | 15634 if (p == NULL) /* out of memory */ |
15470 continue; | 15635 break; |
15471 for (t = p; *t != NUL; ++t) | 15636 for (t = p; *t != NUL; ++t) |
15472 if (*t == '\n') | 15637 if (*t == '\n') |
15473 *t = 'n'; | 15638 *t = 'n'; |
15474 else if (*t == '\r') | 15639 else if (*t == '\r') |
15475 *t = 'r'; | 15640 *t = 'r'; |
15476 if ((fprintf(fd, "let %s = %c%s%c", | 15641 if ((fprintf(fd, "let %s = %c%s%c", |
15477 this_var->v_name, | 15642 this_var->v_name, |
15478 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ', | 15643 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ', |
15479 p, | 15644 p, |
15480 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ') < 0) | 15645 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ') < 0) |
15481 || put_eol(fd) == FAIL) | 15646 || put_eol(fd) == FAIL) |
15482 { | 15647 { |
15648 vim_free(p); | |
15649 return FAIL; | |
15650 } | |
15483 vim_free(p); | 15651 vim_free(p); |
15484 return FAIL; | |
15485 } | 15652 } |
15486 vim_free(p); | |
15487 } | 15653 } |
15488 } | 15654 } |
15489 return OK; | 15655 return OK; |
15490 } | 15656 } |
15491 #endif | 15657 #endif |