comparison src/eval.c @ 76:0ef9cebc4f5d v7.0031

updated for version 7.0031
author vimboss
date Wed, 05 Jan 2005 22:19:46 +0000
parents 7557b6ea0fb1
children d2796c60ca6f
comparison
equal deleted inserted replaced
75:388f285bda1b 76:0ef9cebc4f5d
80 }; 80 };
81 81
82 typedef struct listitem_S listitem; 82 typedef struct listitem_S listitem;
83 83
84 /* 84 /*
85 * Structure to hold the info about a list. 85 * Struct used by those that are using an item in a list.
86 */
87 typedef struct listwatch_S
88 {
89 listitem *lw_item; /* item being watched */
90 struct listwatch_S *lw_next; /* next watcher */
91 } listwatch;
92
93 /*
94 * Structure to hold info about a list.
86 */ 95 */
87 struct listvar_S 96 struct listvar_S
88 { 97 {
89 int lv_refcount; /* reference count */ 98 int lv_refcount; /* reference count */
90 listitem *lv_first; /* first item, NULL if none */ 99 listitem *lv_first; /* first item, NULL if none */
91 listitem *lv_last; /* last item, NULL if none */ 100 listitem *lv_last; /* last item, NULL if none */
101 listwatch *lv_watch; /* first watcher, NULL if none */
92 }; 102 };
93 103
94 typedef struct listvar_S listvar; 104 typedef struct listvar_S listvar;
95 105
96 #define VAR_LIST_MAXNEST 100 /* maximum nesting of lists */ 106 #define VAR_LIST_MAXNEST 100 /* maximum nesting of lists */
166 typeval *rettv; /* return value */ 176 typeval *rettv; /* return value */
167 linenr_T breakpoint; /* next line with breakpoint or zero */ 177 linenr_T breakpoint; /* next line with breakpoint or zero */
168 int dbg_tick; /* debug_tick when breakpoint was set */ 178 int dbg_tick; /* debug_tick when breakpoint was set */
169 int level; /* top nesting level of executed function */ 179 int level; /* top nesting level of executed function */
170 }; 180 };
181
182 /*
183 * Info used by a ":for" loop.
184 */
185 typedef struct forinfo_S
186 {
187 int fi_semicolon; /* TRUE if ending in '; var]' */
188 int fi_varcount; /* nr of variables in the list */
189 listwatch fi_lw; /* keep an eye on the item used. */
190 listvar *fi_list; /* list being used */
191 } forinfo;
192
171 193
172 /* 194 /*
173 * Return the name of the executed function. 195 * Return the name of the executed function.
174 */ 196 */
175 char_u * 197 char_u *
502 #define get_var_string_buf(p, b) get_tv_string_buf(&(p)->tv, (b)) 524 #define get_var_string_buf(p, b) get_tv_string_buf(&(p)->tv, (b))
503 #define get_var_number(p) get_tv_number(&((p)->tv)) 525 #define get_var_number(p) get_tv_number(&((p)->tv))
504 526
505 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 527 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end));
506 528
529 static int ex_let_vars __ARGS((char_u *arg, typeval *tv, int copy, int semicolon, int var_count, char_u *nextchars));
530 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon));
531 static char_u *skip_var_one __ARGS((char_u *arg));
507 static void list_all_vars __ARGS((void)); 532 static void list_all_vars __ARGS((void));
508 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 533 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg));
509 static char_u *ex_let_one __ARGS((char_u *arg, typeval *tv, int copy, char_u *endchars)); 534 static char_u *ex_let_one __ARGS((char_u *arg, typeval *tv, int copy, char_u *endchars));
510 static char_u *set_var_idx __ARGS((char_u *name, char_u *ip, typeval *rettv, int copy, char_u *endchars)); 535 static char_u *set_var_idx __ARGS((char_u *name, char_u *ip, typeval *rettv, int copy, char_u *endchars));
536 static void list_add_watch __ARGS((listvar *l, listwatch *lw));
511 537
512 /* 538 /*
513 * Set an internal variable to a string value. Creates the variable if it does 539 * Set an internal variable to a string value. Creates the variable if it does
514 * not already exist. 540 * not already exist.
515 */ 541 */
1019 char_u *expr = NULL; 1045 char_u *expr = NULL;
1020 typeval rettv; 1046 typeval rettv;
1021 int i; 1047 int i;
1022 int var_count = 0; 1048 int var_count = 0;
1023 int semicolon = 0; 1049 int semicolon = 0;
1024 listvar *l; 1050
1025 listitem *item; 1051 expr = skip_var_list(arg, &var_count, &semicolon);
1026 1052 if (expr == NULL)
1027 if (*arg != '[') 1053 return;
1028 expr = vim_strchr(find_name_end(arg, NULL, NULL, TRUE), '='); 1054 expr = vim_strchr(expr, '=');
1029 if (*arg != '[' && expr == NULL) 1055 if (expr == NULL)
1030 { 1056 {
1031 if (!ends_excmd(*arg)) 1057 if (*arg == '[')
1058 EMSG(_(e_invarg));
1059 else if (!ends_excmd(*arg))
1032 /* ":let var1 var2" */ 1060 /* ":let var1 var2" */
1033 arg = list_arg_vars(eap, arg); 1061 arg = list_arg_vars(eap, arg);
1034 else if (!eap->skip) 1062 else if (!eap->skip)
1035 /* ":let" */ 1063 /* ":let" */
1036 list_all_vars(); 1064 list_all_vars();
1037 eap->nextcmd = check_nextcmd(arg); 1065 eap->nextcmd = check_nextcmd(arg);
1038 } 1066 }
1039 else 1067 else
1040 { 1068 {
1041 if (*arg == '[') 1069 expr = skipwhite(expr + 1);
1042 {
1043 /* ":let [a, b] = expr": find the matching ']' to get to the
1044 * expression. */
1045 while (1)
1046 {
1047 arg = skipwhite(arg + 1);
1048 if (vim_strchr((char_u *)"$@&", *arg) != NULL)
1049 ++arg;
1050 expr = find_name_end(arg, NULL, NULL, TRUE);
1051 if (expr == arg)
1052 {
1053 EMSG2(_(e_invarg2), arg);
1054 return;
1055 }
1056 ++var_count;
1057
1058 arg = skipwhite(expr);
1059 if (*arg == ']')
1060 break;
1061 else if (*arg == ';')
1062 {
1063 if (semicolon == 1)
1064 {
1065 EMSG(_("Double ; in :let"));
1066 return;
1067 }
1068 semicolon = 1;
1069 }
1070 else if (*arg != ',')
1071 {
1072 EMSG2(_(e_invarg2), arg);
1073 return;
1074 }
1075 }
1076
1077 /* check for '=' after the ']' */
1078 expr = skipwhite(arg + 1);
1079 if (*expr != '=')
1080 {
1081 EMSG(_(e_letunexp));
1082 return;
1083 }
1084 }
1085 1070
1086 if (eap->skip) 1071 if (eap->skip)
1087 ++emsg_skip; 1072 ++emsg_skip;
1088 i = eval0(expr + 1, &rettv, &eap->nextcmd, !eap->skip); 1073 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
1089 if (eap->skip) 1074 if (eap->skip)
1090 { 1075 {
1091 if (i != FAIL) 1076 if (i != FAIL)
1092 clear_tv(&rettv); 1077 clear_tv(&rettv);
1093 --emsg_skip; 1078 --emsg_skip;
1094 } 1079 }
1095 else if (i != FAIL) 1080 else if (i != FAIL)
1096 { 1081 {
1097 /* Move "arg" back to the variable name(s). */ 1082 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
1098 arg = eap->arg; 1083 (char_u *)"=");
1099 if (*arg != '[') 1084 clear_tv(&rettv);
1085 }
1086 }
1087 }
1088
1089 /*
1090 * Assign the typevalue "tv" to the variable or variables at "arg_start".
1091 * Handles both "var" with any type and "[var, var; var]" with a list type.
1092 * Returns OK or FAIL;
1093 */
1094 static int
1095 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars)
1096 char_u *arg_start;
1097 typeval *tv;
1098 int copy; /* copy values from "tv", don't move */
1099 int semicolon; /* from skip_var_list() */
1100 int var_count; /* from skip_var_list() */
1101 char_u *nextchars; /* characters that must follow or NULL */
1102 {
1103 char_u *arg = arg_start;
1104 listvar *l;
1105 int i;
1106 listitem *item;
1107 typeval ltv;
1108
1109 if (*arg != '[')
1110 {
1111 /*
1112 * ":let var = expr" or ":for var in list"
1113 */
1114 if (ex_let_one(arg, tv, copy, nextchars) == NULL)
1115 return FAIL;
1116 return OK;
1117 }
1118
1119 /*
1120 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
1121 */
1122 l = tv->vval.v_list;
1123 if (tv->v_type != VAR_LIST || l == NULL)
1124 {
1125 EMSG(_(e_listreq));
1126 return FAIL;
1127 }
1128
1129 i = list_len(l);
1130 if (semicolon == 0 && var_count < i)
1131 {
1132 EMSG(_("E999: Less targets than List items"));
1133 return FAIL;
1134 }
1135 if (var_count - semicolon > i)
1136 {
1137 EMSG(_("E999: More targets than List items"));
1138 return FAIL;
1139 }
1140
1141 item = l->lv_first;
1142 while (*arg != ']')
1143 {
1144 arg = skipwhite(arg + 1);
1145 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]");
1146 item = item->li_next;
1147 if (arg == NULL)
1148 return FAIL;
1149
1150 arg = skipwhite(arg);
1151 if (*arg == ';')
1152 {
1153 /* Put the rest of the list (may be empty) in the var after ';'.
1154 * Create a new list for this. */
1155 l = list_alloc();
1156 if (l == NULL)
1157 return FAIL;
1158 while (item != NULL)
1100 { 1159 {
1101 /* ":let var = expr" */ 1160 list_append_tv(l, &item->li_tv);
1102 (void)ex_let_one(arg, &rettv, FALSE, (char_u *)"="); 1161 item = item->li_next;
1103 } 1162 }
1104 else 1163
1164 ltv.v_type = VAR_LIST;
1165 ltv.vval.v_list = l;
1166 l->lv_refcount = 1;
1167
1168 arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, (char_u *)"]");
1169 clear_tv(&ltv);
1170 if (arg == NULL)
1171 return FAIL;
1172 break;
1173 }
1174 else if (*arg != ',' && *arg != ']')
1175 {
1176 EMSG2(_(e_intern2), "ex_let_vars()");
1177 return FAIL;
1178 }
1179 }
1180
1181 return OK;
1182 }
1183
1184 /*
1185 * Skip over assignable variable "var" or list of variables "[var, var]".
1186 * Used for ":let varvar = expr" and ":for varvar in expr".
1187 * For "[var, var]" increment "*var_count" for each variable.
1188 * for "[var, var; var]" set "semicolon".
1189 * Return NULL for an error.
1190 */
1191 static char_u *
1192 skip_var_list(arg, var_count, semicolon)
1193 char_u *arg;
1194 int *var_count;
1195 int *semicolon;
1196 {
1197 char_u *p, *s;
1198
1199 if (*arg == '[')
1200 {
1201 /* "[var, var]": find the matching ']'. */
1202 p = arg;
1203 while (1)
1204 {
1205 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */
1206 s = skip_var_one(p);
1207 if (s == p)
1105 { 1208 {
1106 /* ":let [v1, v2] = list" */ 1209 EMSG2(_(e_invarg2), p);
1107 l = rettv.vval.v_list; 1210 return NULL;
1108 if (rettv.v_type != VAR_LIST || l == NULL) 1211 }
1109 EMSG(_("E999: List required")); 1212 ++*var_count;
1110 else 1213
1214 p = skipwhite(s);
1215 if (*p == ']')
1216 break;
1217 else if (*p == ';')
1218 {
1219 if (*semicolon == 1)
1111 { 1220 {
1112 i = list_len(l); 1221 EMSG(_("Double ; in list of variables"));
1113 if (semicolon == 0 && var_count < i) 1222 return NULL;
1114 EMSG(_("E999: Less targets than List items"));
1115 else if (var_count - semicolon > i)
1116 EMSG(_("E999: More targets than List items"));
1117 else
1118 {
1119 item = l->lv_first;
1120 while (*arg != ']')
1121 {
1122 arg = skipwhite(arg + 1);
1123 arg = ex_let_one(arg, &item->li_tv,
1124 TRUE, (char_u *)",;]");
1125 item = item->li_next;
1126 if (arg == NULL)
1127 break;
1128
1129 arg = skipwhite(arg);
1130 if (*arg == ';')
1131 {
1132 /* Put the rest of the list (may be empty) in
1133 * the var after ';'. */
1134 l = list_alloc();
1135 if (l == NULL)
1136 break;
1137 while (item != NULL)
1138 {
1139 list_append_tv(l, &item->li_tv);
1140 item = item->li_next;
1141 }
1142 list_unref(rettv.vval.v_list);
1143 rettv.vval.v_list = l;
1144 l->lv_refcount = 1;
1145 (void)ex_let_one(skipwhite(arg + 1), &rettv,
1146 FALSE, (char_u *)"]");
1147 break;
1148 }
1149 else if (*arg != ',' && *arg != ']')
1150 {
1151 EMSG2(_(e_intern2), "ex_let()");
1152 break;
1153 }
1154 }
1155 }
1156 } 1223 }
1224 *semicolon = 1;
1157 } 1225 }
1158 clear_tv(&rettv); 1226 else if (*p != ',')
1159 } 1227 {
1160 } 1228 EMSG2(_(e_invarg2), p);
1229 return NULL;
1230 }
1231 }
1232 return p + 1;
1233 }
1234 else
1235 return skip_var_one(arg);
1236 }
1237
1238 static char_u *
1239 skip_var_one(arg)
1240 char_u *arg;
1241 {
1242 if (vim_strchr((char_u *)"$@&", *arg) != NULL)
1243 ++arg;
1244 return find_name_end(arg, NULL, NULL, TRUE);
1161 } 1245 }
1162 1246
1163 static void 1247 static void
1164 list_all_vars() 1248 list_all_vars()
1165 { 1249 {
1307 static char_u * 1391 static char_u *
1308 ex_let_one(arg, tv, copy, endchars) 1392 ex_let_one(arg, tv, copy, endchars)
1309 char_u *arg; /* points to variable name */ 1393 char_u *arg; /* points to variable name */
1310 typeval *tv; /* value to assign to variable */ 1394 typeval *tv; /* value to assign to variable */
1311 int copy; /* copy value from "tv" */ 1395 int copy; /* copy value from "tv" */
1312 char_u *endchars; /* valid chars after variable name */ 1396 char_u *endchars; /* valid chars after variable name or NULL */
1313 { 1397 {
1314 int c1; 1398 int c1;
1315 char_u *name; 1399 char_u *name;
1316 char_u *p; 1400 char_u *p;
1317 char_u *arg_end = NULL; 1401 char_u *arg_end = NULL;
1329 len = get_env_len(&arg); 1413 len = get_env_len(&arg);
1330 if (len == 0) 1414 if (len == 0)
1331 EMSG2(_(e_invarg2), name - 1); 1415 EMSG2(_(e_invarg2), name - 1);
1332 else 1416 else
1333 { 1417 {
1334 if (vim_strchr(endchars, *skipwhite(arg)) == NULL) 1418 if (endchars != NULL
1419 && vim_strchr(endchars, *skipwhite(arg)) == NULL)
1335 EMSG(_(e_letunexp)); 1420 EMSG(_(e_letunexp));
1336 else 1421 else
1337 { 1422 {
1338 c1 = name[len]; 1423 c1 = name[len];
1339 name[len] = NUL; 1424 name[len] = NUL;
1358 */ 1443 */
1359 else if (*arg == '&') 1444 else if (*arg == '&')
1360 { 1445 {
1361 /* Find the end of the name. */ 1446 /* Find the end of the name. */
1362 p = find_option_end(&arg, &opt_flags); 1447 p = find_option_end(&arg, &opt_flags);
1363 if (p == NULL || vim_strchr(endchars, *skipwhite(p)) == NULL) 1448 if (p == NULL || (endchars != NULL
1449 && vim_strchr(endchars, *skipwhite(p)) == NULL))
1364 EMSG(_(e_letunexp)); 1450 EMSG(_(e_letunexp));
1365 else 1451 else
1366 { 1452 {
1367 c1 = *p; 1453 c1 = *p;
1368 *p = NUL; 1454 *p = NUL;
1377 * ":let @r = expr": Set register contents. 1463 * ":let @r = expr": Set register contents.
1378 */ 1464 */
1379 else if (*arg == '@') 1465 else if (*arg == '@')
1380 { 1466 {
1381 ++arg; 1467 ++arg;
1382 if (vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 1468 if (endchars != NULL
1469 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
1383 EMSG(_(e_letunexp)); 1470 EMSG(_(e_letunexp));
1384 else 1471 else
1385 { 1472 {
1386 write_reg_contents(*arg == '@' ? '"' : *arg, 1473 write_reg_contents(*arg == '@' ? '"' : *arg,
1387 get_tv_string(tv), -1, FALSE); 1474 get_tv_string(tv), -1, FALSE);
1413 if (!aborting()) 1500 if (!aborting())
1414 EMSG2(_(e_invarg2), arg); 1501 EMSG2(_(e_invarg2), arg);
1415 } 1502 }
1416 else if (*p == '[') 1503 else if (*p == '[')
1417 arg_end = set_var_idx(arg, p, tv, copy, endchars); 1504 arg_end = set_var_idx(arg, p, tv, copy, endchars);
1418 else if (vim_strchr(endchars, *skipwhite(p)) == NULL) 1505 else if (endchars != NULL
1506 && vim_strchr(endchars, *skipwhite(p)) == NULL)
1419 EMSG(_(e_letunexp)); 1507 EMSG(_(e_letunexp));
1420 else if (STRNCMP(arg, "b:changedtick", 13) == 0 1508 else if (STRNCMP(arg, "b:changedtick", 13) == 0
1421 && !eval_isnamec(arg[13])) 1509 && !eval_isnamec(arg[13]))
1422 EMSG2(_(e_readonlyvar), arg); 1510 EMSG2(_(e_readonlyvar), arg);
1423 else 1511 else
1503 tv = &item->li_tv; 1591 tv = &item->li_tv;
1504 } 1592 }
1505 1593
1506 if (p != NULL) 1594 if (p != NULL)
1507 { 1595 {
1508 if (vim_strchr(endchars, *p) == NULL) 1596 if (endchars != NULL && vim_strchr(endchars, *p) == NULL)
1509 { 1597 {
1510 EMSG(_(e_letunexp)); 1598 EMSG(_(e_letunexp));
1511 p = NULL; 1599 p = NULL;
1512 } 1600 }
1513 else 1601 else
1523 } 1611 }
1524 } 1612 }
1525 return p; 1613 return p;
1526 } 1614 }
1527 1615
1616 /*
1617 * Add a watcher to a list.
1618 */
1619 static void
1620 list_add_watch(l, lw)
1621 listvar *l;
1622 listwatch *lw;
1623 {
1624 lw->lw_next = l->lv_watch;
1625 l->lv_watch = lw;
1626 }
1627
1628 /*
1629 * Remove a watches from a list.
1630 * No warning when it isn't found...
1631 */
1632 static void
1633 list_rem_watch(l, lwrem)
1634 listvar *l;
1635 listwatch *lwrem;
1636 {
1637 listwatch *lw, **lwp;
1638
1639 lwp = &l->lv_watch;
1640 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
1641 {
1642 if (lw == lwrem)
1643 {
1644 *lwp = lw->lw_next;
1645 break;
1646 }
1647 lwp = &lw->lw_next;
1648 }
1649 }
1650
1651 /*
1652 * Just before removing an item from a list: advance watchers to the next
1653 * item.
1654 */
1655 static void
1656 list_fix_watch(l, item)
1657 listvar *l;
1658 listitem *item;
1659 {
1660 listwatch *lw;
1661
1662 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
1663 if (lw->lw_item == item)
1664 lw->lw_item = item->li_next;
1665 }
1666
1667 /*
1668 * Evaluate the expression used in a ":for var in expr" command.
1669 * "arg" points to "var".
1670 * Set "*errp" to TRUE for an error, FALSE otherwise;
1671 * Return a pointer that holds the info. Null when there is an error.
1672 */
1673 void *
1674 eval_for_line(arg, errp, nextcmdp, skip)
1675 char_u *arg;
1676 int *errp;
1677 char_u **nextcmdp;
1678 int skip;
1679 {
1680 forinfo *fi;
1681 char_u *expr;
1682 typeval tv;
1683 listvar *l;
1684
1685 *errp = TRUE; /* default: there is an error */
1686
1687 fi = (forinfo *)alloc_clear(sizeof(forinfo));
1688 if (fi == NULL)
1689 return NULL;
1690
1691 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
1692 if (expr == NULL)
1693 return fi;
1694
1695 expr = skipwhite(expr);
1696 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2]))
1697 {
1698 EMSG(_("E999: Missing \"in\" after :for"));
1699 return fi;
1700 }
1701
1702 if (skip)
1703 ++emsg_skip;
1704 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK)
1705 {
1706 *errp = FALSE;
1707 if (!skip)
1708 {
1709 l = tv.vval.v_list;
1710 if (tv.v_type != VAR_LIST || l == NULL)
1711 EMSG(_(e_listreq));
1712 else
1713 {
1714 fi->fi_list = l;
1715 list_add_watch(l, &fi->fi_lw);
1716 fi->fi_lw.lw_item = l->lv_first;
1717 }
1718 }
1719 }
1720 if (skip)
1721 --emsg_skip;
1722
1723 return fi;
1724 }
1725
1726 /*
1727 * Use the first item in a ":for" list. Advance to the next.
1728 * Assign the values to the variable (list). "arg" points to the first one.
1729 * Return TRUE when a valid item was found, FALSE when at end of list or
1730 * something wrong.
1731 */
1732 int
1733 next_for_item(fi_void, arg)
1734 void *fi_void;
1735 char_u *arg;
1736 {
1737 forinfo *fi = (forinfo *)fi_void;
1738 int result;
1739 listitem *item;
1740
1741 item = fi->fi_lw.lw_item;
1742 if (item == NULL)
1743 result = FALSE;
1744 else
1745 {
1746 fi->fi_lw.lw_item = item->li_next;
1747 result = (ex_let_vars(arg, &item->li_tv, TRUE,
1748 fi->fi_semicolon, fi->fi_varcount, NULL) == OK);
1749 }
1750 return result;
1751 }
1752
1753 /*
1754 * Free the structure used to store info used by ":for".
1755 */
1756 void
1757 free_for_info(fi_void)
1758 void *fi_void;
1759 {
1760 forinfo *fi = (forinfo *)fi_void;
1761
1762 if (fi->fi_list != NULL)
1763 list_rem_watch(fi->fi_list, &fi->fi_lw);
1764 vim_free(fi);
1765 }
1766
1528 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 1767 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
1529 1768
1530 void 1769 void
1531 set_context_for_expression(xp, arg, cmdidx) 1770 set_context_for_expression(xp, arg, cmdidx)
1532 expand_T *xp; 1771 expand_T *xp;
1533 char_u *arg; 1772 char_u *arg;
1534 cmdidx_T cmdidx; 1773 cmdidx_T cmdidx;
1535 { 1774 {
1536 int got_eq = FALSE; 1775 int got_eq = FALSE;
1537 int c; 1776 int c;
1538 1777 char_u *p;
1539 xp->xp_context = cmdidx == CMD_let ? EXPAND_USER_VARS 1778
1540 : cmdidx == CMD_call ? EXPAND_FUNCTIONS 1779 if (cmdidx == CMD_let)
1541 : EXPAND_EXPRESSION; 1780 {
1781 xp->xp_context = EXPAND_USER_VARS;
1782 if (vim_strchr(arg, '=') == NULL)
1783 {
1784 /* ":let var1 var2 ...": find last space. */
1785 for (p = arg + STRLEN(arg); p > arg; )
1786 {
1787 xp->xp_pattern = p;
1788 p = mb_ptr_back(arg, p);
1789 if (vim_iswhite(*p))
1790 break;
1791 }
1792 return;
1793 }
1794 }
1795 else
1796 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
1797 : EXPAND_EXPRESSION;
1542 while ((xp->xp_pattern = vim_strpbrk(arg, 1798 while ((xp->xp_pattern = vim_strpbrk(arg,
1543 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 1799 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
1544 { 1800 {
1545 c = *xp->xp_pattern; 1801 c = *xp->xp_pattern;
1546 if (c == '&') 1802 if (c == '&')
1599 } 1855 }
1600 else 1856 else
1601 xp->xp_context = EXPAND_EXPRESSION; 1857 xp->xp_context = EXPAND_EXPRESSION;
1602 } 1858 }
1603 else 1859 else
1604 xp->xp_context = EXPAND_NOTHING; 1860 /* Doesn't look like something valid, expand as an expression
1861 * anyway. */
1862 xp->xp_context = EXPAND_EXPRESSION;
1605 arg = xp->xp_pattern; 1863 arg = xp->xp_pattern;
1606 if (*arg != NUL) 1864 if (*arg != NUL)
1607 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 1865 while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
1608 /* skip */ ; 1866 /* skip */ ;
1609 } 1867 }
3301 { 3559 {
3302 return (listitem *)alloc(sizeof(listitem)); 3560 return (listitem *)alloc(sizeof(listitem));
3303 } 3561 }
3304 3562
3305 /* 3563 /*
3306 * Free a list item. Also clears the value; 3564 * Free a list item. Also clears the value. Does not notify watchers.
3307 */ 3565 */
3308 static void 3566 static void
3309 listitem_free(item) 3567 listitem_free(item)
3310 listitem *item; 3568 listitem *item;
3311 { 3569 {
3469 listitem *item; 3727 listitem *item;
3470 3728
3471 item = list_find(l, n); 3729 item = list_find(l, n);
3472 if (item != NULL) 3730 if (item != NULL)
3473 { 3731 {
3732 list_fix_watch(l, item); /* notify watchers */
3474 if (item->li_next == NULL) 3733 if (item->li_next == NULL)
3475 l->lv_last = item->li_prev; 3734 l->lv_last = item->li_prev;
3476 else 3735 else
3477 item->li_next->li_prev = item->li_prev; 3736 item->li_next->li_prev = item->li_prev;
3478 if (item->li_prev == NULL) 3737 if (item->li_prev == NULL)
11804 vir_T *virp; 12063 vir_T *virp;
11805 int writing; 12064 int writing;
11806 { 12065 {
11807 char_u *tab; 12066 char_u *tab;
11808 int is_string = FALSE; 12067 int is_string = FALSE;
11809 typeval *tvp = NULL; 12068 typeval tv;
11810 char_u *val;
11811 12069
11812 if (!writing && (find_viminfo_parameter('!') != NULL)) 12070 if (!writing && (find_viminfo_parameter('!') != NULL))
11813 { 12071 {
11814 tab = vim_strchr(virp->vir_line + 1, '\t'); 12072 tab = vim_strchr(virp->vir_line + 1, '\t');
11815 if (tab != NULL) 12073 if (tab != NULL)
11819 is_string = TRUE; 12077 is_string = TRUE;
11820 12078
11821 tab = vim_strchr(tab, '\t'); 12079 tab = vim_strchr(tab, '\t');
11822 if (tab != NULL) 12080 if (tab != NULL)
11823 { 12081 {
11824 /* create a typeval to hold the value */
11825 if (is_string) 12082 if (is_string)
11826 { 12083 {
11827 val = viminfo_readstring(virp, 12084 tv.v_type = VAR_STRING;
12085 tv.vval.v_string = viminfo_readstring(virp,
11828 (int)(tab - virp->vir_line + 1), TRUE); 12086 (int)(tab - virp->vir_line + 1), TRUE);
11829 if (val != NULL)
11830 tvp = alloc_string_tv(val);
11831 } 12087 }
11832 else 12088 else
11833 { 12089 {
11834 tvp = alloc_tv(); 12090 tv.v_type = VAR_NUMBER;
11835 if (tvp != NULL) 12091 tv.vval.v_number = atol((char *)tab + 1);
11836 {
11837 tvp->v_type = VAR_NUMBER;
11838 tvp->vval.v_number = atol((char *)tab + 1);
11839 }
11840 } 12092 }
11841 /* assign the value to the variable */ 12093 set_var(virp->vir_line + 1, &tv, FALSE);
11842 if (tvp != NULL) 12094 if (is_string)
11843 { 12095 vim_free(tv.vval.v_string);
11844 set_var(virp->vir_line + 1, tvp, FALSE);
11845 free_tv(tvp);
11846 }
11847 } 12096 }
11848 } 12097 }
11849 } 12098 }
11850 12099
11851 return viminfo_readline(virp); 12100 return viminfo_readline(virp);
11876 { 12125 {
11877 switch (this_var->tv.v_type) 12126 switch (this_var->tv.v_type)
11878 { 12127 {
11879 case VAR_STRING: s = "STR"; break; 12128 case VAR_STRING: s = "STR"; break;
11880 case VAR_NUMBER: s = "NUM"; break; 12129 case VAR_NUMBER: s = "NUM"; break;
11881 case VAR_LIST: s = "LST"; break; 12130 default: continue;
11882 case VAR_FUNC: s = "FUN"; break;
11883 default:
11884 EMSGN(_("E999: Internal error: write_viminfo_varlist(): %ld"), (long)this_var->tv.v_type);
11885 s = "ERR";
11886 } 12131 }
11887 fprintf(fp, "!%s\t%s\t", this_var->v_name, s); 12132 fprintf(fp, "!%s\t%s\t", this_var->v_name, s);
11888 viminfo_writestring(fp, tv2string(&this_var->tv, &tofree)); 12133 viminfo_writestring(fp, tv2string(&this_var->tv, &tofree));
11889 vim_free(tofree); 12134 vim_free(tofree);
11890 } 12135 }
11903 char_u *p, *t; 12148 char_u *p, *t;
11904 12149
11905 for (i = gap->ga_len; --i >= 0; ) 12150 for (i = gap->ga_len; --i >= 0; )
11906 { 12151 {
11907 this_var = &VAR_GAP_ENTRY(i, gap); 12152 this_var = &VAR_GAP_ENTRY(i, gap);
11908 if (this_var->v_name != NULL) 12153 if (this_var->v_name != NULL
11909 { 12154 && (this_var->tv.v_type == VAR_NUMBER
11910 if (var_flavour(this_var->v_name) == VAR_FLAVOUR_SESSION) 12155 || this_var->tv.v_type == VAR_STRING)
12156 && var_flavour(this_var->v_name) == VAR_FLAVOUR_SESSION)
12157 {
12158 /* Escape special characters with a backslash. Turn a LF and
12159 * CR into \n and \r. */
12160 p = vim_strsave_escaped(get_var_string(this_var),
12161 (char_u *)"\\\"\n\r");
12162 if (p == NULL) /* out of memory */
12163 continue;
12164 for (t = p; *t != NUL; ++t)
12165 if (*t == '\n')
12166 *t = 'n';
12167 else if (*t == '\r')
12168 *t = 'r';
12169 if ((fprintf(fd, "let %s = %c%s%c",
12170 this_var->v_name,
12171 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ',
12172 p,
12173 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ') < 0)
12174 || put_eol(fd) == FAIL)
11911 { 12175 {
11912 /* Escapse special characters with a backslash. Turn a LF and
11913 * CR into \n and \r. */
11914 p = vim_strsave_escaped(get_var_string(this_var),
11915 (char_u *)"\\\"\n\r");
11916 if (p == NULL) /* out of memory */
11917 continue;
11918 for (t = p; *t != NUL; ++t)
11919 if (*t == '\n')
11920 *t = 'n';
11921 else if (*t == '\r')
11922 *t = 'r';
11923 if ((fprintf(fd, "let %s = %c%s%c",
11924 this_var->v_name,
11925 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ',
11926 p,
11927 (this_var->tv.v_type == VAR_STRING) ? '"' : ' ') < 0)
11928 || put_eol(fd) == FAIL)
11929 {
11930 vim_free(p);
11931 return FAIL;
11932 }
11933 vim_free(p); 12176 vim_free(p);
12177 return FAIL;
11934 } 12178 }
11935 12179 vim_free(p);
11936 } 12180 }
11937 } 12181 }
11938 return OK; 12182 return OK;
11939 } 12183 }
11940 #endif 12184 #endif