Mercurial > vim
comparison src/eval.c @ 88:2b4debdc8d2c v7.0035
updated for version 7.0035
author | vimboss |
---|---|
date | Sat, 08 Jan 2005 21:49:45 +0000 |
parents | 8173ec1e9f1f |
children | a9e90b3356b6 |
comparison
equal
deleted
inserted
replaced
87:014ba200db86 | 88:2b4debdc8d2c |
---|---|
322 static void listitem_free __ARGS((listitem *item)); | 322 static void listitem_free __ARGS((listitem *item)); |
323 static long list_len __ARGS((listvar *l)); | 323 static long list_len __ARGS((listvar *l)); |
324 static int list_equal __ARGS((listvar *l1, listvar *l2, int ic)); | 324 static int list_equal __ARGS((listvar *l1, listvar *l2, int ic)); |
325 static int tv_equal __ARGS((typeval *tv1, typeval *tv2, int ic)); | 325 static int tv_equal __ARGS((typeval *tv1, typeval *tv2, int ic)); |
326 static listitem *list_find __ARGS((listvar *l, long n)); | 326 static listitem *list_find __ARGS((listvar *l, long n)); |
327 static long list_idx_of_item __ARGS((listvar *l, listitem *item)); | |
327 static listitem *list_find_ext __ARGS((listvar *l, long *ip)); | 328 static listitem *list_find_ext __ARGS((listvar *l, long *ip)); |
328 static void list_append __ARGS((listvar *l, listitem *item)); | 329 static void list_append __ARGS((listvar *l, listitem *item)); |
329 static int list_append_tv __ARGS((listvar *l, typeval *tv)); | 330 static int list_append_tv __ARGS((listvar *l, typeval *tv)); |
330 static int list_insert_tv __ARGS((listvar *l, typeval *tv, listitem *item)); | 331 static int list_insert_tv __ARGS((listvar *l, typeval *tv, listitem *item)); |
331 static int list_extend __ARGS((listvar *l1, listvar *l2, listitem *bef)); | 332 static int list_extend __ARGS((listvar *l1, listvar *l2, listitem *bef)); |
438 static void f_maparg __ARGS((typeval *argvars, typeval *rettv)); | 439 static void f_maparg __ARGS((typeval *argvars, typeval *rettv)); |
439 static void f_mapcheck __ARGS((typeval *argvars, typeval *rettv)); | 440 static void f_mapcheck __ARGS((typeval *argvars, typeval *rettv)); |
440 static void f_match __ARGS((typeval *argvars, typeval *rettv)); | 441 static void f_match __ARGS((typeval *argvars, typeval *rettv)); |
441 static void f_matchend __ARGS((typeval *argvars, typeval *rettv)); | 442 static void f_matchend __ARGS((typeval *argvars, typeval *rettv)); |
442 static void f_matchstr __ARGS((typeval *argvars, typeval *rettv)); | 443 static void f_matchstr __ARGS((typeval *argvars, typeval *rettv)); |
444 static void f_max __ARGS((typeval *argvars, typeval *rettv)); | |
445 static void f_min __ARGS((typeval *argvars, typeval *rettv)); | |
443 static void f_mode __ARGS((typeval *argvars, typeval *rettv)); | 446 static void f_mode __ARGS((typeval *argvars, typeval *rettv)); |
444 static void f_nextnonblank __ARGS((typeval *argvars, typeval *rettv)); | 447 static void f_nextnonblank __ARGS((typeval *argvars, typeval *rettv)); |
445 static void f_nr2char __ARGS((typeval *argvars, typeval *rettv)); | 448 static void f_nr2char __ARGS((typeval *argvars, typeval *rettv)); |
446 static void f_prevnonblank __ARGS((typeval *argvars, typeval *rettv)); | 449 static void f_prevnonblank __ARGS((typeval *argvars, typeval *rettv)); |
447 static void f_remote_expr __ARGS((typeval *argvars, typeval *rettv)); | 450 static void f_remote_expr __ARGS((typeval *argvars, typeval *rettv)); |
1538 | 1541 |
1539 return arg_end; | 1542 return arg_end; |
1540 } | 1543 } |
1541 | 1544 |
1542 /* | 1545 /* |
1543 * Set a variable with an index: "name[expr]", "name[expr][expr]", etc. | 1546 * Set a variable with an index: "name[expr]", "name[expr:expr]", |
1544 * Only works if "name" is an existing List. | 1547 * "name[expr][expr]", etc. Only works if "name" is an existing List. |
1545 * "ip" points to the first '['. | 1548 * "ip" points to the first '['. |
1546 * Returns a pointer to just after the last used ']'; NULL for error. | 1549 * Returns a pointer to just after the last used ']'; NULL for error. |
1547 */ | 1550 */ |
1548 static char_u * | 1551 static char_u * |
1549 set_var_idx(name, ip, rettv, copy, endchars) | 1552 set_var_idx(name, ip, rettv, copy, endchars) |
1555 { | 1558 { |
1556 VAR v; | 1559 VAR v; |
1557 int c1; | 1560 int c1; |
1558 char_u *p; | 1561 char_u *p; |
1559 typeval var1; | 1562 typeval var1; |
1563 typeval var2; | |
1564 int range = FALSE; | |
1560 typeval *tv; | 1565 typeval *tv; |
1561 long n; | 1566 long n1 = 0, n2 = 0; |
1562 listitem *item; | 1567 int empty1, empty2 = FALSE; |
1568 listitem *item = NULL; | |
1569 listitem *ni; | |
1570 listitem *ri; | |
1571 listvar *l = NULL; | |
1563 | 1572 |
1564 c1 = *ip; | 1573 c1 = *ip; |
1565 *ip = NUL; | 1574 *ip = NUL; |
1566 v = find_var(name, TRUE); | 1575 v = find_var(name, TRUE); |
1567 if (v == NULL) | 1576 if (v == NULL) |
1577 { | 1586 { |
1578 EMSG(_("E689: Can only index a List")); | 1587 EMSG(_("E689: Can only index a List")); |
1579 p = NULL; | 1588 p = NULL; |
1580 break; | 1589 break; |
1581 } | 1590 } |
1582 p = skipwhite(p + 1); | 1591 if (range) |
1583 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ | 1592 { |
1584 { | 1593 EMSG(_("E708: [:] must come last")); |
1585 p = NULL; | 1594 p = NULL; |
1586 break; | 1595 break; |
1587 } | 1596 } |
1597 | |
1598 /* Get the index [expr] or the first index [expr: ]. */ | |
1599 p = skipwhite(p + 1); | |
1600 if (*p == ':') | |
1601 empty1 = TRUE; | |
1602 else | |
1603 { | |
1604 empty1 = FALSE; | |
1605 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ | |
1606 { | |
1607 p = NULL; | |
1608 break; | |
1609 } | |
1610 } | |
1611 | |
1612 /* Optionally get the second index [ :expr]. */ | |
1613 if (*p == ':') | |
1614 { | |
1615 if (rettv->v_type != VAR_LIST || rettv->vval.v_list == NULL) | |
1616 { | |
1617 EMSG(_("E709: [:] requires a List value")); | |
1618 p = NULL; | |
1619 if (!empty1) | |
1620 clear_tv(&var1); | |
1621 break; | |
1622 } | |
1623 p = skipwhite(p + 1); | |
1624 if (*p == ']') | |
1625 empty2 = TRUE; | |
1626 else | |
1627 { | |
1628 empty2 = FALSE; | |
1629 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ | |
1630 { | |
1631 p = NULL; | |
1632 if (!empty1) | |
1633 clear_tv(&var1); | |
1634 break; | |
1635 } | |
1636 } | |
1637 range = TRUE; | |
1638 } | |
1639 else | |
1640 range = FALSE; | |
1641 | |
1588 if (*p != ']') | 1642 if (*p != ']') |
1589 { | 1643 { |
1590 EMSG(_(e_missbrac)); | 1644 EMSG(_(e_missbrac)); |
1591 clear_tv(&var1); | 1645 if (!empty1) |
1646 clear_tv(&var1); | |
1647 if (range && !empty2) | |
1648 clear_tv(&var2); | |
1592 p = NULL; | 1649 p = NULL; |
1593 break; | 1650 break; |
1594 } | 1651 } |
1595 n = get_tv_number(&var1); | 1652 |
1596 clear_tv(&var1); | 1653 /* |
1597 item = list_find(tv->vval.v_list, n); | 1654 * Get the number and item for the only or first index. |
1655 */ | |
1656 if (empty1) | |
1657 n1 = 0; | |
1658 else | |
1659 { | |
1660 n1 = get_tv_number(&var1); | |
1661 clear_tv(&var1); | |
1662 } | |
1663 l = tv->vval.v_list; | |
1664 item = list_find(l, n1); | |
1598 if (item == NULL) | 1665 if (item == NULL) |
1599 { | 1666 { |
1600 EMSGN(_(e_listidx), n); | 1667 EMSGN(_(e_listidx), n1); |
1601 p = NULL; | 1668 p = NULL; |
1669 if (range && !empty2) | |
1670 clear_tv(&var2); | |
1602 break; | 1671 break; |
1603 } | 1672 } |
1673 | |
1674 /* | |
1675 * May need to find the item or absolute index for the second index of | |
1676 * a range. | |
1677 * When no index given: "empty2" is TRUE. | |
1678 * Otherwise "n2" is set to the second index. | |
1679 */ | |
1680 if (range && !empty2) | |
1681 { | |
1682 n2 = get_tv_number(&var2); | |
1683 clear_tv(&var2); | |
1684 if (n2 < 0) | |
1685 { | |
1686 ni = list_find(l, n2); | |
1687 if (ni == NULL) | |
1688 { | |
1689 EMSGN(_(e_listidx), n2); | |
1690 p = NULL; | |
1691 break; | |
1692 } | |
1693 n2 = list_idx_of_item(l, ni); | |
1694 } | |
1695 | |
1696 /* Check that n2 isn't before n1. */ | |
1697 if (n1 < 0) | |
1698 n1 = list_idx_of_item(l, item); | |
1699 if (n2 < n1) | |
1700 { | |
1701 EMSGN(_(e_listidx), n2); | |
1702 p = NULL; | |
1703 break; | |
1704 } | |
1705 } | |
1706 | |
1604 tv = &item->li_tv; | 1707 tv = &item->li_tv; |
1605 } | 1708 } |
1606 | 1709 |
1607 if (p != NULL) | 1710 if (p != NULL) |
1608 { | 1711 { |
1609 if (endchars != NULL && vim_strchr(endchars, *p) == NULL) | 1712 if (endchars != NULL && vim_strchr(endchars, *p) == NULL) |
1610 { | 1713 { |
1611 EMSG(_(e_letunexp)); | 1714 EMSG(_(e_letunexp)); |
1612 p = NULL; | 1715 p = NULL; |
1613 } | 1716 } |
1717 else if (range) | |
1718 { | |
1719 /* | |
1720 * Assign the List values to the list items. | |
1721 */ | |
1722 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) | |
1723 { | |
1724 clear_tv(&item->li_tv); | |
1725 copy_tv(&ri->li_tv, &item->li_tv); | |
1726 ri = ri->li_next; | |
1727 if (ri == NULL || (!empty2 && n2 == n1)) | |
1728 break; | |
1729 if (item->li_next == NULL) | |
1730 { | |
1731 /* Need to add an empty item. */ | |
1732 ni = listitem_alloc(); | |
1733 if (ni == NULL) | |
1734 { | |
1735 ri = NULL; | |
1736 break; | |
1737 } | |
1738 ni->li_tv.v_type = VAR_NUMBER; | |
1739 ni->li_tv.vval.v_number = 0; | |
1740 list_append(l, ni); | |
1741 } | |
1742 item = item->li_next; | |
1743 ++n1; | |
1744 } | |
1745 if (ri != NULL) | |
1746 EMSG(_("E710: List value has more items than target")); | |
1747 else if (empty2 ? item != NULL && item->li_next != NULL : n1 != n2) | |
1748 EMSG(_("E711: List value has not enough items")); | |
1749 } | |
1614 else | 1750 else |
1615 { | 1751 { |
1752 /* | |
1753 * Assign the value to the variable or list item. | |
1754 */ | |
1616 clear_tv(tv); | 1755 clear_tv(tv); |
1617 if (copy) | 1756 if (copy) |
1618 copy_tv(tv, rettv); | 1757 copy_tv(rettv, tv); |
1619 else | 1758 else |
1620 { | 1759 { |
1621 *tv = *rettv; | 1760 *tv = *rettv; |
1622 init_tv(rettv); | 1761 init_tv(rettv); |
1623 } | 1762 } |
3780 ++idx; | 3919 ++idx; |
3781 } | 3920 } |
3782 if (idx != n) | 3921 if (idx != n) |
3783 return NULL; | 3922 return NULL; |
3784 return item; | 3923 return item; |
3924 } | |
3925 | |
3926 /* | |
3927 * Locate "item" list "l" and return its index. | |
3928 * Returns -1 when "item" is not in the list. | |
3929 */ | |
3930 static long | |
3931 list_idx_of_item(l, item) | |
3932 listvar *l; | |
3933 listitem *item; | |
3934 { | |
3935 long idx = 0; | |
3936 listitem *li; | |
3937 | |
3938 if (l == NULL) | |
3939 return -1; | |
3940 idx = 0; | |
3941 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) | |
3942 ++idx; | |
3943 if (li == NULL) | |
3944 return -1; | |
3945 return idx;; | |
3785 } | 3946 } |
3786 | 3947 |
3787 /* | 3948 /* |
3788 * Like list_find(), but also find an item just past the end. | 3949 * Like list_find(), but also find an item just past the end. |
3789 * "*ip" is the item to find. | 3950 * "*ip" is the item to find. |
4251 {"maparg", 1, 2, f_maparg}, | 4412 {"maparg", 1, 2, f_maparg}, |
4252 {"mapcheck", 1, 2, f_mapcheck}, | 4413 {"mapcheck", 1, 2, f_mapcheck}, |
4253 {"match", 2, 4, f_match}, | 4414 {"match", 2, 4, f_match}, |
4254 {"matchend", 2, 4, f_matchend}, | 4415 {"matchend", 2, 4, f_matchend}, |
4255 {"matchstr", 2, 4, f_matchstr}, | 4416 {"matchstr", 2, 4, f_matchstr}, |
4417 {"max", 1, 1, f_max}, | |
4418 {"min", 1, 1, f_min}, | |
4256 {"mode", 0, 0, f_mode}, | 4419 {"mode", 0, 0, f_mode}, |
4257 {"nextnonblank", 1, 1, f_nextnonblank}, | 4420 {"nextnonblank", 1, 1, f_nextnonblank}, |
4258 {"nr2char", 1, 1, f_nr2char}, | 4421 {"nr2char", 1, 1, f_nr2char}, |
4259 {"prevnonblank", 1, 1, f_prevnonblank}, | 4422 {"prevnonblank", 1, 1, f_prevnonblank}, |
4260 {"remote_expr", 2, 3, f_remote_expr}, | 4423 {"remote_expr", 2, 3, f_remote_expr}, |
8081 f_matchstr(argvars, rettv) | 8244 f_matchstr(argvars, rettv) |
8082 typeval *argvars; | 8245 typeval *argvars; |
8083 typeval *rettv; | 8246 typeval *rettv; |
8084 { | 8247 { |
8085 find_some_match(argvars, rettv, 2); | 8248 find_some_match(argvars, rettv, 2); |
8249 } | |
8250 | |
8251 static void max_min __ARGS((typeval *argvars, typeval *rettv, int domax)); | |
8252 | |
8253 static void | |
8254 max_min(argvars, rettv, domax) | |
8255 typeval *argvars; | |
8256 typeval *rettv; | |
8257 int domax; | |
8258 { | |
8259 listvar *l; | |
8260 listitem *li; | |
8261 long n = 0; | |
8262 long i; | |
8263 | |
8264 if (argvars[0].v_type == VAR_LIST) | |
8265 { | |
8266 l = argvars[0].vval.v_list; | |
8267 if (l != NULL) | |
8268 { | |
8269 li = l->lv_first; | |
8270 if (li != NULL) | |
8271 { | |
8272 n = get_tv_number(&li->li_tv); | |
8273 while (1) | |
8274 { | |
8275 li = li->li_next; | |
8276 if (li == NULL) | |
8277 break; | |
8278 i = get_tv_number(&li->li_tv); | |
8279 if (domax ? i > n : i < n) | |
8280 n = i; | |
8281 } | |
8282 } | |
8283 } | |
8284 } | |
8285 else | |
8286 EMSG(_(e_listreq)); | |
8287 rettv->vval.v_number = n; | |
8288 } | |
8289 | |
8290 /* | |
8291 * "max()" function | |
8292 */ | |
8293 static void | |
8294 f_max(argvars, rettv) | |
8295 typeval *argvars; | |
8296 typeval *rettv; | |
8297 { | |
8298 max_min(argvars, rettv, TRUE); | |
8299 } | |
8300 | |
8301 /* | |
8302 * "min()" function | |
8303 */ | |
8304 static void | |
8305 f_min(argvars, rettv) | |
8306 typeval *argvars; | |
8307 typeval *rettv; | |
8308 { | |
8309 max_min(argvars, rettv, FALSE); | |
8086 } | 8310 } |
8087 | 8311 |
8088 /* | 8312 /* |
8089 * "mode()" function | 8313 * "mode()" function |
8090 */ | 8314 */ |
10245 static void | 10469 static void |
10246 f_type(argvars, rettv) | 10470 f_type(argvars, rettv) |
10247 typeval *argvars; | 10471 typeval *argvars; |
10248 typeval *rettv; | 10472 typeval *rettv; |
10249 { | 10473 { |
10250 if (argvars[0].v_type == VAR_NUMBER) | 10474 int n; |
10251 rettv->vval.v_number = 0; | 10475 |
10252 else | 10476 switch (argvars[0].v_type) |
10253 rettv->vval.v_number = 1; | 10477 { |
10478 case VAR_NUMBER: n = 0; break; | |
10479 case VAR_STRING: n = 1; break; | |
10480 case VAR_FUNC: n = 2; break; | |
10481 case VAR_LIST: n = 3; break; | |
10482 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; | |
10483 } | |
10484 rettv->vval.v_number = n; | |
10254 } | 10485 } |
10255 | 10486 |
10256 /* | 10487 /* |
10257 * "virtcol(string)" function | 10488 * "virtcol(string)" function |
10258 */ | 10489 */ |