Mercurial > vim
comparison src/eval.c @ 19181:94eda51ba9ba v8.2.0149
patch 8.2.0149: maintaining a Vim9 branch separately is more work
Commit: https://github.com/vim/vim/commit/8a7d6542b33e5d2b352262305c3bfdb2d14e1cf8
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 26 15:56:19 2020 +0100
patch 8.2.0149: maintaining a Vim9 branch separately is more work
Problem: Maintaining a Vim9 branch separately is more work.
Solution: Merge the Vim9 script changes.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 26 Jan 2020 16:00:05 +0100 |
parents | 44c6498535c9 |
children | 133ef7ba4e4e |
comparison
equal
deleted
inserted
replaced
19180:8edf0aeb71b9 | 19181:94eda51ba9ba |
---|---|
18 | 18 |
19 #ifdef VMS | 19 #ifdef VMS |
20 # include <float.h> | 20 # include <float.h> |
21 #endif | 21 #endif |
22 | 22 |
23 static char *e_missbrac = N_("E111: Missing ']'"); | |
24 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); | 23 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); |
25 #ifdef FEAT_FLOAT | 24 #ifdef FEAT_FLOAT |
26 static char *e_float_as_string = N_("E806: using Float as a String"); | 25 static char *e_float_as_string = N_("E806: using Float as a String"); |
27 #endif | 26 #endif |
28 static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); | |
29 | 27 |
30 #define NAMESPACE_CHAR (char_u *)"abglstvw" | 28 #define NAMESPACE_CHAR (char_u *)"abglstvw" |
31 | 29 |
32 /* | 30 /* |
33 * When recursively copying lists and dicts we need to remember which ones we | 31 * When recursively copying lists and dicts we need to remember which ones we |
58 static int eval5(char_u **arg, typval_T *rettv, int evaluate); | 56 static int eval5(char_u **arg, typval_T *rettv, int evaluate); |
59 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); | 57 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); |
60 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string); | 58 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string); |
61 static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp); | 59 static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp); |
62 | 60 |
63 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); | |
64 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); | |
65 static int free_unref_items(int copyID); | 61 static int free_unref_items(int copyID); |
66 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); | |
67 static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); | 62 static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); |
68 static int tv_check_lock(typval_T *tv, char_u *name, int use_gettext); | 63 static int tv_check_lock(typval_T *tv, char_u *name, int use_gettext); |
69 | 64 |
70 /* | 65 /* |
71 * Return "n1" divided by "n2", taking care of dividing by zero. | 66 * Return "n1" divided by "n2", taking care of dividing by zero. |
220 semsg(_(e_invexpr2), start); | 215 semsg(_(e_invexpr2), start); |
221 } | 216 } |
222 return ret; | 217 return ret; |
223 } | 218 } |
224 | 219 |
220 /* | |
221 * Evaluate an expression, which can be a function, partial or string. | |
222 * Pass arguments "argv[argc]". | |
223 * Return the result in "rettv" and OK or FAIL. | |
224 */ | |
225 int | 225 int |
226 eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv) | 226 eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv) |
227 { | 227 { |
228 char_u *s; | 228 char_u *s; |
229 char_u buf[NUMBUFLEN]; | 229 char_u buf[NUMBUFLEN]; |
241 } | 241 } |
242 else if (expr->v_type == VAR_PARTIAL) | 242 else if (expr->v_type == VAR_PARTIAL) |
243 { | 243 { |
244 partial_T *partial = expr->vval.v_partial; | 244 partial_T *partial = expr->vval.v_partial; |
245 | 245 |
246 s = partial_name(partial); | 246 if (partial->pt_func != NULL && partial->pt_func->uf_dfunc_idx >= 0) |
247 if (s == NULL || *s == NUL) | 247 { |
248 return FAIL; | 248 if (call_def_function(partial->pt_func, argc, argv, rettv) == FAIL) |
249 vim_memset(&funcexe, 0, sizeof(funcexe)); | 249 return FAIL; |
250 funcexe.evaluate = TRUE; | 250 } |
251 funcexe.partial = partial; | 251 else |
252 if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) | 252 { |
253 return FAIL; | 253 s = partial_name(partial); |
254 if (s == NULL || *s == NUL) | |
255 return FAIL; | |
256 vim_memset(&funcexe, 0, sizeof(funcexe)); | |
257 funcexe.evaluate = TRUE; | |
258 funcexe.partial = partial; | |
259 if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) | |
260 return FAIL; | |
261 } | |
254 } | 262 } |
255 else | 263 else |
256 { | 264 { |
257 s = tv_get_string_buf_chk(expr, buf); | 265 s = tv_get_string_buf_chk(expr, buf); |
258 if (s == NULL) | 266 if (s == NULL) |
650 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); | 658 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); |
651 } | 659 } |
652 | 660 |
653 // Find the end of the name. | 661 // Find the end of the name. |
654 p = find_name_end(name, &expr_start, &expr_end, fne_flags); | 662 p = find_name_end(name, &expr_start, &expr_end, fne_flags); |
663 lp->ll_name_end = p; | |
655 if (expr_start != NULL) | 664 if (expr_start != NULL) |
656 { | 665 { |
657 // Don't expand the name when we already know there is an error. | 666 // Don't expand the name when we already know there is an error. |
658 if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p) | 667 if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p) |
659 && *p != '[' && *p != '.') | 668 && *p != '[' && *p != '.') |
676 } | 685 } |
677 } | 686 } |
678 lp->ll_name = lp->ll_exp_name; | 687 lp->ll_name = lp->ll_exp_name; |
679 } | 688 } |
680 else | 689 else |
690 { | |
681 lp->ll_name = name; | 691 lp->ll_name = name; |
692 | |
693 if (current_sctx.sc_version == SCRIPT_VERSION_VIM9 && *p == ':') | |
694 { | |
695 scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid); | |
696 char_u *tp = skipwhite(p + 1); | |
697 | |
698 // parse the type after the name | |
699 lp->ll_type = parse_type(&tp, &si->sn_type_list); | |
700 lp->ll_name_end = tp; | |
701 } | |
702 } | |
682 | 703 |
683 // Without [idx] or .key we are done. | 704 // Without [idx] or .key we are done. |
684 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) | 705 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) |
685 return p; | 706 return p; |
686 | 707 |
1000 lp->ll_tv = &lp->ll_li->li_tv; | 1021 lp->ll_tv = &lp->ll_li->li_tv; |
1001 } | 1022 } |
1002 } | 1023 } |
1003 | 1024 |
1004 clear_tv(&var1); | 1025 clear_tv(&var1); |
1026 lp->ll_name_end = p; | |
1005 return p; | 1027 return p; |
1006 } | 1028 } |
1007 | 1029 |
1008 /* | 1030 /* |
1009 * Clear lval "lp" that was filled by get_lval(). | 1031 * Clear lval "lp" that was filled by get_lval(). |
1025 set_var_lval( | 1047 set_var_lval( |
1026 lval_T *lp, | 1048 lval_T *lp, |
1027 char_u *endp, | 1049 char_u *endp, |
1028 typval_T *rettv, | 1050 typval_T *rettv, |
1029 int copy, | 1051 int copy, |
1030 int is_const, // Disallow to modify existing variable for :const | 1052 int flags, // LET_IS_CONST and/or LET_NO_COMMAND |
1031 char_u *op) | 1053 char_u *op) |
1032 { | 1054 { |
1033 int cc; | 1055 int cc; |
1034 listitem_T *ri; | 1056 listitem_T *ri; |
1035 dictitem_T *di; | 1057 dictitem_T *di; |
1091 } | 1113 } |
1092 else if (op != NULL && *op != '=') | 1114 else if (op != NULL && *op != '=') |
1093 { | 1115 { |
1094 typval_T tv; | 1116 typval_T tv; |
1095 | 1117 |
1096 if (is_const) | 1118 if (flags & LET_IS_CONST) |
1097 { | 1119 { |
1098 emsg(_(e_cannot_mod)); | 1120 emsg(_(e_cannot_mod)); |
1099 *endp = cc; | 1121 *endp = cc; |
1100 return; | 1122 return; |
1101 } | 1123 } |
1112 set_var(lp->ll_name, &tv, FALSE); | 1134 set_var(lp->ll_name, &tv, FALSE); |
1113 clear_tv(&tv); | 1135 clear_tv(&tv); |
1114 } | 1136 } |
1115 } | 1137 } |
1116 else | 1138 else |
1117 set_var_const(lp->ll_name, rettv, copy, is_const); | 1139 set_var_const(lp->ll_name, lp->ll_type, rettv, copy, flags); |
1118 *endp = cc; | 1140 *endp = cc; |
1119 } | 1141 } |
1120 else if (var_check_lock(lp->ll_newkey == NULL | 1142 else if (var_check_lock(lp->ll_newkey == NULL |
1121 ? lp->ll_tv->v_lock | 1143 ? lp->ll_tv->v_lock |
1122 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) | 1144 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) |
1124 else if (lp->ll_range) | 1146 else if (lp->ll_range) |
1125 { | 1147 { |
1126 listitem_T *ll_li = lp->ll_li; | 1148 listitem_T *ll_li = lp->ll_li; |
1127 int ll_n1 = lp->ll_n1; | 1149 int ll_n1 = lp->ll_n1; |
1128 | 1150 |
1129 if (is_const) | 1151 if (flags & LET_IS_CONST) |
1130 { | 1152 { |
1131 emsg(_("E996: Cannot lock a range")); | 1153 emsg(_("E996: Cannot lock a range")); |
1132 return; | 1154 return; |
1133 } | 1155 } |
1134 | 1156 |
1183 else | 1205 else |
1184 { | 1206 { |
1185 /* | 1207 /* |
1186 * Assign to a List or Dictionary item. | 1208 * Assign to a List or Dictionary item. |
1187 */ | 1209 */ |
1188 if (is_const) | 1210 if (flags & LET_IS_CONST) |
1189 { | 1211 { |
1190 emsg(_("E996: Cannot lock a list or dict")); | 1212 emsg(_("E996: Cannot lock a list or dict")); |
1191 return; | 1213 return; |
1192 } | 1214 } |
1193 if (lp->ll_newkey != NULL) | 1215 if (lp->ll_newkey != NULL) |
1248 && tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL) | 1270 && tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL) |
1249 { | 1271 { |
1250 switch (tv1->v_type) | 1272 switch (tv1->v_type) |
1251 { | 1273 { |
1252 case VAR_UNKNOWN: | 1274 case VAR_UNKNOWN: |
1275 case VAR_VOID: | |
1253 case VAR_DICT: | 1276 case VAR_DICT: |
1254 case VAR_FUNC: | 1277 case VAR_FUNC: |
1255 case VAR_PARTIAL: | 1278 case VAR_PARTIAL: |
1256 case VAR_BOOL: | 1279 case VAR_BOOL: |
1257 case VAR_SPECIAL: | 1280 case VAR_SPECIAL: |
1390 | 1413 |
1391 fi = ALLOC_CLEAR_ONE(forinfo_T); | 1414 fi = ALLOC_CLEAR_ONE(forinfo_T); |
1392 if (fi == NULL) | 1415 if (fi == NULL) |
1393 return NULL; | 1416 return NULL; |
1394 | 1417 |
1395 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); | 1418 expr = skip_var_list(arg, TRUE, &fi->fi_varcount, &fi->fi_semicolon); |
1396 if (expr == NULL) | 1419 if (expr == NULL) |
1397 return fi; | 1420 return fi; |
1398 | 1421 |
1399 expr = skipwhite(expr); | 1422 expr = skipwhite(expr); |
1400 if (expr[0] != 'i' || expr[1] != 'n' || !VIM_ISWHITE(expr[2])) | 1423 if (expr[0] != 'i' || expr[1] != 'n' || !VIM_ISWHITE(expr[2])) |
1401 { | 1424 { |
1402 emsg(_("E690: Missing \"in\" after :for")); | 1425 emsg(_(e_missing_in)); |
1403 return fi; | 1426 return fi; |
1404 } | 1427 } |
1405 | 1428 |
1406 if (skip) | 1429 if (skip) |
1407 ++emsg_skip; | 1430 ++emsg_skip; |
1418 // a null list is like an empty list: do nothing | 1441 // a null list is like an empty list: do nothing |
1419 clear_tv(&tv); | 1442 clear_tv(&tv); |
1420 } | 1443 } |
1421 else | 1444 else |
1422 { | 1445 { |
1446 // Need a real list here. | |
1447 range_list_materialize(l); | |
1448 | |
1423 // No need to increment the refcount, it's already set for | 1449 // No need to increment the refcount, it's already set for |
1424 // the list being used in "tv". | 1450 // the list being used in "tv". |
1425 fi->fi_list = l; | 1451 fi->fi_list = l; |
1426 list_add_watch(l, &fi->fi_lw); | 1452 list_add_watch(l, &fi->fi_lw); |
1427 fi->fi_lw.lw_item = l->lv_first; | 1453 fi->fi_lw.lw_item = l->lv_first; |
1434 { | 1460 { |
1435 typval_T btv; | 1461 typval_T btv; |
1436 | 1462 |
1437 // Make a copy, so that the iteration still works when the | 1463 // Make a copy, so that the iteration still works when the |
1438 // blob is changed. | 1464 // blob is changed. |
1439 blob_copy(&tv, &btv); | 1465 blob_copy(tv.vval.v_blob, &btv); |
1440 fi->fi_blob = btv.vval.v_blob; | 1466 fi->fi_blob = btv.vval.v_blob; |
1441 } | 1467 } |
1442 clear_tv(&tv); | 1468 clear_tv(&tv); |
1443 } | 1469 } |
1444 else | 1470 else |
1476 tv.v_type = VAR_NUMBER; | 1502 tv.v_type = VAR_NUMBER; |
1477 tv.v_lock = VAR_FIXED; | 1503 tv.v_lock = VAR_FIXED; |
1478 tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi); | 1504 tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi); |
1479 ++fi->fi_bi; | 1505 ++fi->fi_bi; |
1480 return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon, | 1506 return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon, |
1481 fi->fi_varcount, FALSE, NULL) == OK; | 1507 fi->fi_varcount, 0, NULL) == OK; |
1482 } | 1508 } |
1483 | 1509 |
1484 item = fi->fi_lw.lw_item; | 1510 item = fi->fi_lw.lw_item; |
1485 if (item == NULL) | 1511 if (item == NULL) |
1486 result = FALSE; | 1512 result = FALSE; |
1487 else | 1513 else |
1488 { | 1514 { |
1489 fi->fi_lw.lw_item = item->li_next; | 1515 fi->fi_lw.lw_item = item->li_next; |
1490 result = (ex_let_vars(arg, &item->li_tv, TRUE, fi->fi_semicolon, | 1516 result = (ex_let_vars(arg, &item->li_tv, TRUE, fi->fi_semicolon, |
1491 fi->fi_varcount, FALSE, NULL) == OK); | 1517 fi->fi_varcount, 0, NULL) == OK); |
1492 } | 1518 } |
1493 return result; | 1519 return result; |
1494 } | 1520 } |
1495 | 1521 |
1496 /* | 1522 /* |
1812 /* | 1838 /* |
1813 * Check for the ":". | 1839 * Check for the ":". |
1814 */ | 1840 */ |
1815 if ((*arg)[0] != ':') | 1841 if ((*arg)[0] != ':') |
1816 { | 1842 { |
1817 emsg(_("E109: Missing ':' after '?'")); | 1843 emsg(_(e_missing_colon)); |
1818 if (evaluate && result) | 1844 if (evaluate && result) |
1819 clear_tv(rettv); | 1845 clear_tv(rettv); |
1820 return FAIL; | 1846 return FAIL; |
1821 } | 1847 } |
1822 | 1848 |
2087 } | 2113 } |
2088 | 2114 |
2089 return OK; | 2115 return OK; |
2090 } | 2116 } |
2091 | 2117 |
2118 void | |
2119 eval_addblob(typval_T *tv1, typval_T *tv2) | |
2120 { | |
2121 blob_T *b1 = tv1->vval.v_blob; | |
2122 blob_T *b2 = tv2->vval.v_blob; | |
2123 blob_T *b = blob_alloc(); | |
2124 int i; | |
2125 | |
2126 if (b != NULL) | |
2127 { | |
2128 for (i = 0; i < blob_len(b1); i++) | |
2129 ga_append(&b->bv_ga, blob_get(b1, i)); | |
2130 for (i = 0; i < blob_len(b2); i++) | |
2131 ga_append(&b->bv_ga, blob_get(b2, i)); | |
2132 | |
2133 clear_tv(tv1); | |
2134 rettv_blob_set(tv1, b); | |
2135 } | |
2136 } | |
2137 | |
2138 int | |
2139 eval_addlist(typval_T *tv1, typval_T *tv2) | |
2140 { | |
2141 typval_T var3; | |
2142 | |
2143 // concatenate Lists | |
2144 if (list_concat(tv1->vval.v_list, tv2->vval.v_list, &var3) == FAIL) | |
2145 { | |
2146 clear_tv(tv1); | |
2147 clear_tv(tv2); | |
2148 return FAIL; | |
2149 } | |
2150 clear_tv(tv1); | |
2151 *tv1 = var3; | |
2152 return OK; | |
2153 } | |
2154 | |
2092 /* | 2155 /* |
2093 * Handle fourth level expression: | 2156 * Handle fourth level expression: |
2094 * + number addition | 2157 * + number addition |
2095 * - number subtraction | 2158 * - number subtraction |
2096 * . string concatenation (if script version is 1) | 2159 * . string concatenation (if script version is 1) |
2103 */ | 2166 */ |
2104 static int | 2167 static int |
2105 eval5(char_u **arg, typval_T *rettv, int evaluate) | 2168 eval5(char_u **arg, typval_T *rettv, int evaluate) |
2106 { | 2169 { |
2107 typval_T var2; | 2170 typval_T var2; |
2108 typval_T var3; | |
2109 int op; | 2171 int op; |
2110 varnumber_T n1, n2; | 2172 varnumber_T n1, n2; |
2111 #ifdef FEAT_FLOAT | 2173 #ifdef FEAT_FLOAT |
2112 float_T f1 = 0, f2 = 0; | 2174 float_T f1 = 0, f2 = 0; |
2113 #endif | 2175 #endif |
2187 rettv->v_type = VAR_STRING; | 2249 rettv->v_type = VAR_STRING; |
2188 rettv->vval.v_string = p; | 2250 rettv->vval.v_string = p; |
2189 } | 2251 } |
2190 else if (op == '+' && rettv->v_type == VAR_BLOB | 2252 else if (op == '+' && rettv->v_type == VAR_BLOB |
2191 && var2.v_type == VAR_BLOB) | 2253 && var2.v_type == VAR_BLOB) |
2192 { | 2254 eval_addblob(rettv, &var2); |
2193 blob_T *b1 = rettv->vval.v_blob; | |
2194 blob_T *b2 = var2.vval.v_blob; | |
2195 blob_T *b = blob_alloc(); | |
2196 int i; | |
2197 | |
2198 if (b != NULL) | |
2199 { | |
2200 for (i = 0; i < blob_len(b1); i++) | |
2201 ga_append(&b->bv_ga, blob_get(b1, i)); | |
2202 for (i = 0; i < blob_len(b2); i++) | |
2203 ga_append(&b->bv_ga, blob_get(b2, i)); | |
2204 | |
2205 clear_tv(rettv); | |
2206 rettv_blob_set(rettv, b); | |
2207 } | |
2208 } | |
2209 else if (op == '+' && rettv->v_type == VAR_LIST | 2255 else if (op == '+' && rettv->v_type == VAR_LIST |
2210 && var2.v_type == VAR_LIST) | 2256 && var2.v_type == VAR_LIST) |
2211 { | 2257 { |
2212 // concatenate Lists | 2258 if (eval_addlist(rettv, &var2) == FAIL) |
2213 if (list_concat(rettv->vval.v_list, var2.vval.v_list, | |
2214 &var3) == FAIL) | |
2215 { | |
2216 clear_tv(rettv); | |
2217 clear_tv(&var2); | |
2218 return FAIL; | 2259 return FAIL; |
2219 } | |
2220 clear_tv(rettv); | |
2221 *rettv = var3; | |
2222 } | 2260 } |
2223 else | 2261 else |
2224 { | 2262 { |
2225 int error = FALSE; | 2263 int error = FALSE; |
2226 | 2264 |
2422 f1 = f1 / f2; | 2460 f1 = f1 / f2; |
2423 # endif | 2461 # endif |
2424 } | 2462 } |
2425 else | 2463 else |
2426 { | 2464 { |
2427 emsg(_("E804: Cannot use '%' with Float")); | 2465 emsg(_(e_modulus)); |
2428 return FAIL; | 2466 return FAIL; |
2429 } | 2467 } |
2430 rettv->v_type = VAR_FLOAT; | 2468 rettv->v_type = VAR_FLOAT; |
2431 rettv->vval.v_float = f1; | 2469 rettv->vval.v_float = f1; |
2432 } | 2470 } |
2460 * identifier variable value | 2498 * identifier variable value |
2461 * function() function call | 2499 * function() function call |
2462 * $VAR environment variable | 2500 * $VAR environment variable |
2463 * (expression) nested expression | 2501 * (expression) nested expression |
2464 * [expr, expr] List | 2502 * [expr, expr] List |
2503 * {arg, arg -> expr} Lambda | |
2465 * {key: val, key: val} Dictionary | 2504 * {key: val, key: val} Dictionary |
2466 * #{key: val, key: val} Dictionary with literal keys | 2505 * #{key: val, key: val} Dictionary with literal keys |
2467 * | 2506 * |
2468 * Also handle: | 2507 * Also handle: |
2469 * ! in front logical NOT | 2508 * ! in front logical NOT |
2481 static int | 2520 static int |
2482 eval7( | 2521 eval7( |
2483 char_u **arg, | 2522 char_u **arg, |
2484 typval_T *rettv, | 2523 typval_T *rettv, |
2485 int evaluate, | 2524 int evaluate, |
2486 int want_string UNUSED) // after "." operator | 2525 int want_string) // after "." operator |
2487 { | 2526 { |
2488 varnumber_T n; | |
2489 int len; | 2527 int len; |
2490 char_u *s; | 2528 char_u *s; |
2491 char_u *start_leader, *end_leader; | 2529 char_u *start_leader, *end_leader; |
2492 int ret = OK; | 2530 int ret = OK; |
2493 char_u *alias; | 2531 char_u *alias; |
2530 case '5': | 2568 case '5': |
2531 case '6': | 2569 case '6': |
2532 case '7': | 2570 case '7': |
2533 case '8': | 2571 case '8': |
2534 case '9': | 2572 case '9': |
2535 case '.': | 2573 case '.': ret = get_number_tv(arg, rettv, evaluate, want_string); |
2536 { | |
2537 #ifdef FEAT_FLOAT | |
2538 char_u *p; | |
2539 int get_float = FALSE; | |
2540 | |
2541 // We accept a float when the format matches | |
2542 // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very | |
2543 // strict to avoid backwards compatibility problems. | |
2544 // With script version 2 and later the leading digit can be | |
2545 // omitted. | |
2546 // Don't look for a float after the "." operator, so that | |
2547 // ":let vers = 1.2.3" doesn't fail. | |
2548 if (**arg == '.') | |
2549 p = *arg; | |
2550 else | |
2551 p = skipdigits(*arg + 1); | |
2552 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) | |
2553 { | |
2554 get_float = TRUE; | |
2555 p = skipdigits(p + 2); | |
2556 if (*p == 'e' || *p == 'E') | |
2557 { | |
2558 ++p; | |
2559 if (*p == '-' || *p == '+') | |
2560 ++p; | |
2561 if (!vim_isdigit(*p)) | |
2562 get_float = FALSE; | |
2563 else | |
2564 p = skipdigits(p + 1); | |
2565 } | |
2566 if (ASCII_ISALPHA(*p) || *p == '.') | |
2567 get_float = FALSE; | |
2568 } | |
2569 if (get_float) | |
2570 { | |
2571 float_T f; | |
2572 | |
2573 *arg += string2float(*arg, &f); | |
2574 if (evaluate) | |
2575 { | |
2576 rettv->v_type = VAR_FLOAT; | |
2577 rettv->vval.v_float = f; | |
2578 } | |
2579 } | |
2580 else | |
2581 #endif | |
2582 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z')) | |
2583 { | |
2584 char_u *bp; | |
2585 blob_T *blob = NULL; // init for gcc | |
2586 | |
2587 // Blob constant: 0z0123456789abcdef | |
2588 if (evaluate) | |
2589 blob = blob_alloc(); | |
2590 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2) | |
2591 { | |
2592 if (!vim_isxdigit(bp[1])) | |
2593 { | |
2594 if (blob != NULL) | |
2595 { | |
2596 emsg(_("E973: Blob literal should have an even number of hex characters")); | |
2597 ga_clear(&blob->bv_ga); | |
2598 VIM_CLEAR(blob); | |
2599 } | |
2600 ret = FAIL; | |
2601 break; | |
2602 } | |
2603 if (blob != NULL) | |
2604 ga_append(&blob->bv_ga, | |
2605 (hex2nr(*bp) << 4) + hex2nr(*(bp+1))); | |
2606 if (bp[2] == '.' && vim_isxdigit(bp[3])) | |
2607 ++bp; | |
2608 } | |
2609 if (blob != NULL) | |
2610 rettv_blob_set(rettv, blob); | |
2611 *arg = bp; | |
2612 } | |
2613 else | |
2614 { | |
2615 // decimal, hex or octal number | |
2616 vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4 | |
2617 ? STR2NR_NO_OCT + STR2NR_QUOTE | |
2618 : STR2NR_ALL, &n, NULL, 0, TRUE); | |
2619 if (len == 0) | |
2620 { | |
2621 semsg(_(e_invexpr2), *arg); | |
2622 ret = FAIL; | |
2623 break; | |
2624 } | |
2625 *arg += len; | |
2626 if (evaluate) | |
2627 { | |
2628 rettv->v_type = VAR_NUMBER; | |
2629 rettv->vval.v_number = n; | |
2630 } | |
2631 } | |
2632 break; | 2574 break; |
2633 } | |
2634 | 2575 |
2635 /* | 2576 /* |
2636 * String constant: "string". | 2577 * String constant: "string". |
2637 */ | 2578 */ |
2638 case '"': ret = get_string_tv(arg, rettv, evaluate); | 2579 case '"': ret = get_string_tv(arg, rettv, evaluate); |
2645 break; | 2586 break; |
2646 | 2587 |
2647 /* | 2588 /* |
2648 * List: [expr, expr] | 2589 * List: [expr, expr] |
2649 */ | 2590 */ |
2650 case '[': ret = get_list_tv(arg, rettv, evaluate); | 2591 case '[': ret = get_list_tv(arg, rettv, evaluate, TRUE); |
2651 break; | 2592 break; |
2652 | 2593 |
2653 /* | 2594 /* |
2654 * Dictionary: #{key: val, key: val} | 2595 * Dictionary: #{key: val, key: val} |
2655 */ | 2596 */ |
2704 ret = eval1(arg, rettv, evaluate); // recursive! | 2645 ret = eval1(arg, rettv, evaluate); // recursive! |
2705 if (**arg == ')') | 2646 if (**arg == ')') |
2706 ++*arg; | 2647 ++*arg; |
2707 else if (ret == OK) | 2648 else if (ret == OK) |
2708 { | 2649 { |
2709 emsg(_("E110: Missing ')'")); | 2650 emsg(_(e_missing_close)); |
2710 clear_tv(rettv); | 2651 clear_tv(rettv); |
2711 ret = FAIL; | 2652 ret = FAIL; |
2712 } | 2653 } |
2713 break; | 2654 break; |
2714 | 2655 |
2905 if (verbose) | 2846 if (verbose) |
2906 { | 2847 { |
2907 if (*skipwhite(*arg) == '(') | 2848 if (*skipwhite(*arg) == '(') |
2908 semsg(_(e_nowhitespace)); | 2849 semsg(_(e_nowhitespace)); |
2909 else | 2850 else |
2910 semsg(_(e_missingparen), "lambda"); | 2851 semsg(_(e_missing_paren), "lambda"); |
2911 } | 2852 } |
2912 clear_tv(rettv); | 2853 clear_tv(rettv); |
2913 ret = FAIL; | 2854 ret = FAIL; |
2914 } | 2855 } |
2915 else | 2856 else |
2959 else | 2900 else |
2960 { | 2901 { |
2961 if (**arg != '(') | 2902 if (**arg != '(') |
2962 { | 2903 { |
2963 if (verbose) | 2904 if (verbose) |
2964 semsg(_(e_missingparen), name); | 2905 semsg(_(e_missing_paren), name); |
2965 ret = FAIL; | 2906 ret = FAIL; |
2966 } | 2907 } |
2967 else if (VIM_ISWHITE((*arg)[-1])) | 2908 else if (VIM_ISWHITE((*arg)[-1])) |
2968 { | 2909 { |
2969 if (verbose) | 2910 if (verbose) |
3022 case VAR_CHANNEL: | 2963 case VAR_CHANNEL: |
3023 if (verbose) | 2964 if (verbose) |
3024 emsg(_("E909: Cannot index a special variable")); | 2965 emsg(_("E909: Cannot index a special variable")); |
3025 return FAIL; | 2966 return FAIL; |
3026 case VAR_UNKNOWN: | 2967 case VAR_UNKNOWN: |
2968 case VAR_VOID: | |
3027 if (evaluate) | 2969 if (evaluate) |
3028 return FAIL; | 2970 return FAIL; |
3029 // FALLTHROUGH | 2971 // FALLTHROUGH |
3030 | 2972 |
3031 case VAR_STRING: | 2973 case VAR_STRING: |
3127 } | 3069 } |
3128 | 3070 |
3129 switch (rettv->v_type) | 3071 switch (rettv->v_type) |
3130 { | 3072 { |
3131 case VAR_UNKNOWN: | 3073 case VAR_UNKNOWN: |
3074 case VAR_VOID: | |
3132 case VAR_FUNC: | 3075 case VAR_FUNC: |
3133 case VAR_PARTIAL: | 3076 case VAR_PARTIAL: |
3134 case VAR_FLOAT: | 3077 case VAR_FLOAT: |
3135 case VAR_BOOL: | 3078 case VAR_BOOL: |
3136 case VAR_SPECIAL: | 3079 case VAR_SPECIAL: |
3375 rettv == NULL ? NULL : &stringval, opt_flags); | 3318 rettv == NULL ? NULL : &stringval, opt_flags); |
3376 | 3319 |
3377 if (opt_type == -3) // invalid name | 3320 if (opt_type == -3) // invalid name |
3378 { | 3321 { |
3379 if (rettv != NULL) | 3322 if (rettv != NULL) |
3380 semsg(_("E113: Unknown option: %s"), *arg); | 3323 semsg(_(e_unknown_option), *arg); |
3381 ret = FAIL; | 3324 ret = FAIL; |
3382 } | 3325 } |
3383 else if (rettv != NULL) | 3326 else if (rettv != NULL) |
3384 { | 3327 { |
3385 if (opt_type == -2) // hidden string option | 3328 if (opt_type == -2) // hidden string option |
3411 | 3354 |
3412 return ret; | 3355 return ret; |
3413 } | 3356 } |
3414 | 3357 |
3415 /* | 3358 /* |
3359 * Allocate a variable for a number constant. Also deals with "0z" for blob. | |
3360 * Return OK or FAIL. | |
3361 */ | |
3362 int | |
3363 get_number_tv( | |
3364 char_u **arg, | |
3365 typval_T *rettv, | |
3366 int evaluate, | |
3367 int want_string UNUSED) | |
3368 { | |
3369 int len; | |
3370 #ifdef FEAT_FLOAT | |
3371 char_u *p; | |
3372 int get_float = FALSE; | |
3373 | |
3374 // We accept a float when the format matches | |
3375 // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very | |
3376 // strict to avoid backwards compatibility problems. | |
3377 // With script version 2 and later the leading digit can be | |
3378 // omitted. | |
3379 // Don't look for a float after the "." operator, so that | |
3380 // ":let vers = 1.2.3" doesn't fail. | |
3381 if (**arg == '.') | |
3382 p = *arg; | |
3383 else | |
3384 p = skipdigits(*arg + 1); | |
3385 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) | |
3386 { | |
3387 get_float = TRUE; | |
3388 p = skipdigits(p + 2); | |
3389 if (*p == 'e' || *p == 'E') | |
3390 { | |
3391 ++p; | |
3392 if (*p == '-' || *p == '+') | |
3393 ++p; | |
3394 if (!vim_isdigit(*p)) | |
3395 get_float = FALSE; | |
3396 else | |
3397 p = skipdigits(p + 1); | |
3398 } | |
3399 if (ASCII_ISALPHA(*p) || *p == '.') | |
3400 get_float = FALSE; | |
3401 } | |
3402 if (get_float) | |
3403 { | |
3404 float_T f; | |
3405 | |
3406 *arg += string2float(*arg, &f); | |
3407 if (evaluate) | |
3408 { | |
3409 rettv->v_type = VAR_FLOAT; | |
3410 rettv->vval.v_float = f; | |
3411 } | |
3412 } | |
3413 else | |
3414 #endif | |
3415 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z')) | |
3416 { | |
3417 char_u *bp; | |
3418 blob_T *blob = NULL; // init for gcc | |
3419 | |
3420 // Blob constant: 0z0123456789abcdef | |
3421 if (evaluate) | |
3422 blob = blob_alloc(); | |
3423 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2) | |
3424 { | |
3425 if (!vim_isxdigit(bp[1])) | |
3426 { | |
3427 if (blob != NULL) | |
3428 { | |
3429 emsg(_("E973: Blob literal should have an even number of hex characters")); | |
3430 ga_clear(&blob->bv_ga); | |
3431 VIM_CLEAR(blob); | |
3432 } | |
3433 return FAIL; | |
3434 } | |
3435 if (blob != NULL) | |
3436 ga_append(&blob->bv_ga, | |
3437 (hex2nr(*bp) << 4) + hex2nr(*(bp+1))); | |
3438 if (bp[2] == '.' && vim_isxdigit(bp[3])) | |
3439 ++bp; | |
3440 } | |
3441 if (blob != NULL) | |
3442 rettv_blob_set(rettv, blob); | |
3443 *arg = bp; | |
3444 } | |
3445 else | |
3446 { | |
3447 varnumber_T n; | |
3448 | |
3449 // decimal, hex or octal number | |
3450 vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4 | |
3451 ? STR2NR_NO_OCT + STR2NR_QUOTE | |
3452 : STR2NR_ALL, &n, NULL, 0, TRUE); | |
3453 if (len == 0) | |
3454 { | |
3455 semsg(_(e_invexpr2), *arg); | |
3456 return FAIL; | |
3457 } | |
3458 *arg += len; | |
3459 if (evaluate) | |
3460 { | |
3461 rettv->v_type = VAR_NUMBER; | |
3462 rettv->vval.v_number = n; | |
3463 } | |
3464 } | |
3465 return OK; | |
3466 } | |
3467 | |
3468 /* | |
3416 * Allocate a variable for a string constant. | 3469 * Allocate a variable for a string constant. |
3417 * Return OK or FAIL. | 3470 * Return OK or FAIL. |
3418 */ | 3471 */ |
3419 static int | 3472 int |
3420 get_string_tv(char_u **arg, typval_T *rettv, int evaluate) | 3473 get_string_tv(char_u **arg, typval_T *rettv, int evaluate) |
3421 { | 3474 { |
3422 char_u *p; | 3475 char_u *p; |
3423 char_u *name; | 3476 char_u *name; |
3424 int extra = 0; | 3477 int extra = 0; |
3551 | 3604 |
3552 /* | 3605 /* |
3553 * Allocate a variable for a 'str''ing' constant. | 3606 * Allocate a variable for a 'str''ing' constant. |
3554 * Return OK or FAIL. | 3607 * Return OK or FAIL. |
3555 */ | 3608 */ |
3556 static int | 3609 int |
3557 get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) | 3610 get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) |
3558 { | 3611 { |
3559 char_u *p; | 3612 char_u *p; |
3560 char_u *str; | 3613 char_u *str; |
3561 int reduce = 0; | 3614 int reduce = 0; |
3770 | 3823 |
3771 case VAR_BLOB: | 3824 case VAR_BLOB: |
3772 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob); | 3825 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob); |
3773 | 3826 |
3774 case VAR_NUMBER: | 3827 case VAR_NUMBER: |
3828 case VAR_BOOL: | |
3829 case VAR_SPECIAL: | |
3775 return tv1->vval.v_number == tv2->vval.v_number; | 3830 return tv1->vval.v_number == tv2->vval.v_number; |
3776 | 3831 |
3777 case VAR_STRING: | 3832 case VAR_STRING: |
3778 s1 = tv_get_string_buf(tv1, buf1); | 3833 s1 = tv_get_string_buf(tv1, buf1); |
3779 s2 = tv_get_string_buf(tv2, buf2); | 3834 s2 = tv_get_string_buf(tv2, buf2); |
3780 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); | 3835 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); |
3781 | |
3782 case VAR_BOOL: | |
3783 case VAR_SPECIAL: | |
3784 return tv1->vval.v_number == tv2->vval.v_number; | |
3785 | 3836 |
3786 case VAR_FLOAT: | 3837 case VAR_FLOAT: |
3787 #ifdef FEAT_FLOAT | 3838 #ifdef FEAT_FLOAT |
3788 return tv1->vval.v_float == tv2->vval.v_float; | 3839 return tv1->vval.v_float == tv2->vval.v_float; |
3789 #endif | 3840 #endif |
3793 #endif | 3844 #endif |
3794 case VAR_CHANNEL: | 3845 case VAR_CHANNEL: |
3795 #ifdef FEAT_JOB_CHANNEL | 3846 #ifdef FEAT_JOB_CHANNEL |
3796 return tv1->vval.v_channel == tv2->vval.v_channel; | 3847 return tv1->vval.v_channel == tv2->vval.v_channel; |
3797 #endif | 3848 #endif |
3849 | |
3798 case VAR_FUNC: | 3850 case VAR_FUNC: |
3799 case VAR_PARTIAL: | 3851 case VAR_PARTIAL: |
3800 case VAR_UNKNOWN: | 3852 case VAR_UNKNOWN: |
3853 case VAR_VOID: | |
3801 break; | 3854 break; |
3802 } | 3855 } |
3803 | 3856 |
3804 // VAR_UNKNOWN can be the result of a invalid expression, let's say it | 3857 // VAR_UNKNOWN can be the result of a invalid expression, let's say it |
3805 // does not equal anything, not even itself. | 3858 // does not equal anything, not even itself. |
4509 } | 4562 } |
4510 break; | 4563 break; |
4511 | 4564 |
4512 case VAR_NUMBER: | 4565 case VAR_NUMBER: |
4513 case VAR_UNKNOWN: | 4566 case VAR_UNKNOWN: |
4567 case VAR_VOID: | |
4514 *tofree = NULL; | 4568 *tofree = NULL; |
4515 r = tv_get_string_buf(tv, numbuf); | 4569 r = tv_get_string_buf(tv, numbuf); |
4516 break; | 4570 break; |
4517 | 4571 |
4518 case VAR_JOB: | 4572 case VAR_JOB: |
4666 * Get the value of an environment variable. | 4720 * Get the value of an environment variable. |
4667 * "arg" is pointing to the '$'. It is advanced to after the name. | 4721 * "arg" is pointing to the '$'. It is advanced to after the name. |
4668 * If the environment variable was not set, silently assume it is empty. | 4722 * If the environment variable was not set, silently assume it is empty. |
4669 * Return FAIL if the name is invalid. | 4723 * Return FAIL if the name is invalid. |
4670 */ | 4724 */ |
4671 static int | 4725 int |
4672 get_env_tv(char_u **arg, typval_T *rettv, int evaluate) | 4726 get_env_tv(char_u **arg, typval_T *rettv, int evaluate) |
4673 { | 4727 { |
4674 char_u *string = NULL; | 4728 char_u *string = NULL; |
4675 int len; | 4729 int len; |
4676 int cc; | 4730 int cc; |
5361 break; | 5415 break; |
5362 #endif | 5416 #endif |
5363 case VAR_NUMBER: | 5417 case VAR_NUMBER: |
5364 case VAR_FLOAT: | 5418 case VAR_FLOAT: |
5365 case VAR_UNKNOWN: | 5419 case VAR_UNKNOWN: |
5420 case VAR_VOID: | |
5366 case VAR_BOOL: | 5421 case VAR_BOOL: |
5367 case VAR_SPECIAL: | 5422 case VAR_SPECIAL: |
5368 break; | 5423 break; |
5369 } | 5424 } |
5370 vim_free(varp); | 5425 vim_free(varp); |
5423 #ifdef FEAT_JOB_CHANNEL | 5478 #ifdef FEAT_JOB_CHANNEL |
5424 channel_unref(varp->vval.v_channel); | 5479 channel_unref(varp->vval.v_channel); |
5425 varp->vval.v_channel = NULL; | 5480 varp->vval.v_channel = NULL; |
5426 #endif | 5481 #endif |
5427 case VAR_UNKNOWN: | 5482 case VAR_UNKNOWN: |
5483 case VAR_VOID: | |
5428 break; | 5484 break; |
5429 } | 5485 } |
5430 varp->v_lock = 0; | 5486 varp->v_lock = 0; |
5431 } | 5487 } |
5432 } | 5488 } |
5501 #endif | 5557 #endif |
5502 case VAR_BLOB: | 5558 case VAR_BLOB: |
5503 emsg(_("E974: Using a Blob as a Number")); | 5559 emsg(_("E974: Using a Blob as a Number")); |
5504 break; | 5560 break; |
5505 case VAR_UNKNOWN: | 5561 case VAR_UNKNOWN: |
5562 case VAR_VOID: | |
5506 internal_error("tv_get_number(UNKNOWN)"); | 5563 internal_error("tv_get_number(UNKNOWN)"); |
5507 break; | 5564 break; |
5508 } | 5565 } |
5509 if (denote == NULL) // useful for values that must be unsigned | 5566 if (denote == NULL) // useful for values that must be unsigned |
5510 n = -1; | 5567 n = -1; |
5554 # endif | 5611 # endif |
5555 case VAR_BLOB: | 5612 case VAR_BLOB: |
5556 emsg(_("E975: Using a Blob as a Float")); | 5613 emsg(_("E975: Using a Blob as a Float")); |
5557 break; | 5614 break; |
5558 case VAR_UNKNOWN: | 5615 case VAR_UNKNOWN: |
5616 case VAR_VOID: | |
5559 internal_error("tv_get_float(UNKNOWN)"); | 5617 internal_error("tv_get_float(UNKNOWN)"); |
5560 break; | 5618 break; |
5561 } | 5619 } |
5562 return 0; | 5620 return 0; |
5563 } | 5621 } |
5676 return buf; | 5734 return buf; |
5677 } | 5735 } |
5678 #endif | 5736 #endif |
5679 break; | 5737 break; |
5680 case VAR_UNKNOWN: | 5738 case VAR_UNKNOWN: |
5739 case VAR_VOID: | |
5681 emsg(_(e_inval_string)); | 5740 emsg(_(e_inval_string)); |
5682 break; | 5741 break; |
5683 } | 5742 } |
5684 return NULL; | 5743 return NULL; |
5685 } | 5744 } |
5824 to->vval.v_dict = from->vval.v_dict; | 5883 to->vval.v_dict = from->vval.v_dict; |
5825 ++to->vval.v_dict->dv_refcount; | 5884 ++to->vval.v_dict->dv_refcount; |
5826 } | 5885 } |
5827 break; | 5886 break; |
5828 case VAR_UNKNOWN: | 5887 case VAR_UNKNOWN: |
5888 case VAR_VOID: | |
5829 internal_error("copy_tv(UNKNOWN)"); | 5889 internal_error("copy_tv(UNKNOWN)"); |
5830 break; | 5890 break; |
5831 } | 5891 } |
5832 } | 5892 } |
5833 | 5893 |
5883 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); | 5943 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); |
5884 if (to->vval.v_list == NULL) | 5944 if (to->vval.v_list == NULL) |
5885 ret = FAIL; | 5945 ret = FAIL; |
5886 break; | 5946 break; |
5887 case VAR_BLOB: | 5947 case VAR_BLOB: |
5888 ret = blob_copy(from, to); | 5948 ret = blob_copy(from->vval.v_blob, to); |
5889 break; | 5949 break; |
5890 case VAR_DICT: | 5950 case VAR_DICT: |
5891 to->v_type = VAR_DICT; | 5951 to->v_type = VAR_DICT; |
5892 to->v_lock = 0; | 5952 to->v_lock = 0; |
5893 if (from->vval.v_dict == NULL) | 5953 if (from->vval.v_dict == NULL) |
5902 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); | 5962 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); |
5903 if (to->vval.v_dict == NULL) | 5963 if (to->vval.v_dict == NULL) |
5904 ret = FAIL; | 5964 ret = FAIL; |
5905 break; | 5965 break; |
5906 case VAR_UNKNOWN: | 5966 case VAR_UNKNOWN: |
5967 case VAR_VOID: | |
5907 internal_error("item_copy(UNKNOWN)"); | 5968 internal_error("item_copy(UNKNOWN)"); |
5908 ret = FAIL; | 5969 ret = FAIL; |
5909 } | 5970 } |
5910 --recurse; | 5971 --recurse; |
5911 return ret; | 5972 return ret; |
5973 } | |
5974 | |
5975 void | |
5976 echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr) | |
5977 { | |
5978 char_u *tofree; | |
5979 char_u numbuf[NUMBUFLEN]; | |
5980 char_u *p = echo_string(rettv, &tofree, numbuf, get_copyID()); | |
5981 | |
5982 if (*atstart) | |
5983 { | |
5984 *atstart = FALSE; | |
5985 // Call msg_start() after eval1(), evaluating the expression | |
5986 // may cause a message to appear. | |
5987 if (with_space) | |
5988 { | |
5989 // Mark the saved text as finishing the line, so that what | |
5990 // follows is displayed on a new line when scrolling back | |
5991 // at the more prompt. | |
5992 msg_sb_eol(); | |
5993 msg_start(); | |
5994 } | |
5995 } | |
5996 else if (with_space) | |
5997 msg_puts_attr(" ", echo_attr); | |
5998 | |
5999 if (p != NULL) | |
6000 for ( ; *p != NUL && !got_int; ++p) | |
6001 { | |
6002 if (*p == '\n' || *p == '\r' || *p == TAB) | |
6003 { | |
6004 if (*p != TAB && *needclr) | |
6005 { | |
6006 // remove any text still there from the command | |
6007 msg_clr_eos(); | |
6008 *needclr = FALSE; | |
6009 } | |
6010 msg_putchar_attr(*p, echo_attr); | |
6011 } | |
6012 else | |
6013 { | |
6014 if (has_mbyte) | |
6015 { | |
6016 int i = (*mb_ptr2len)(p); | |
6017 | |
6018 (void)msg_outtrans_len_attr(p, i, echo_attr); | |
6019 p += i - 1; | |
6020 } | |
6021 else | |
6022 (void)msg_outtrans_len_attr(p, 1, echo_attr); | |
6023 } | |
6024 } | |
6025 vim_free(tofree); | |
5912 } | 6026 } |
5913 | 6027 |
5914 /* | 6028 /* |
5915 * ":echo expr1 ..." print each argument separated with a space, add a | 6029 * ":echo expr1 ..." print each argument separated with a space, add a |
5916 * newline at the end. | 6030 * newline at the end. |
5919 void | 6033 void |
5920 ex_echo(exarg_T *eap) | 6034 ex_echo(exarg_T *eap) |
5921 { | 6035 { |
5922 char_u *arg = eap->arg; | 6036 char_u *arg = eap->arg; |
5923 typval_T rettv; | 6037 typval_T rettv; |
5924 char_u *tofree; | |
5925 char_u *p; | 6038 char_u *p; |
5926 int needclr = TRUE; | 6039 int needclr = TRUE; |
5927 int atstart = TRUE; | 6040 int atstart = TRUE; |
5928 char_u numbuf[NUMBUFLEN]; | |
5929 int did_emsg_before = did_emsg; | 6041 int did_emsg_before = did_emsg; |
5930 int called_emsg_before = called_emsg; | 6042 int called_emsg_before = called_emsg; |
5931 | 6043 |
5932 if (eap->skip) | 6044 if (eap->skip) |
5933 ++emsg_skip; | 6045 ++emsg_skip; |
5952 break; | 6064 break; |
5953 } | 6065 } |
5954 need_clr_eos = FALSE; | 6066 need_clr_eos = FALSE; |
5955 | 6067 |
5956 if (!eap->skip) | 6068 if (!eap->skip) |
5957 { | 6069 echo_one(&rettv, eap->cmdidx == CMD_echo, &atstart, &needclr); |
5958 if (atstart) | 6070 |
5959 { | |
5960 atstart = FALSE; | |
5961 // Call msg_start() after eval1(), evaluating the expression | |
5962 // may cause a message to appear. | |
5963 if (eap->cmdidx == CMD_echo) | |
5964 { | |
5965 // Mark the saved text as finishing the line, so that what | |
5966 // follows is displayed on a new line when scrolling back | |
5967 // at the more prompt. | |
5968 msg_sb_eol(); | |
5969 msg_start(); | |
5970 } | |
5971 } | |
5972 else if (eap->cmdidx == CMD_echo) | |
5973 msg_puts_attr(" ", echo_attr); | |
5974 p = echo_string(&rettv, &tofree, numbuf, get_copyID()); | |
5975 if (p != NULL) | |
5976 for ( ; *p != NUL && !got_int; ++p) | |
5977 { | |
5978 if (*p == '\n' || *p == '\r' || *p == TAB) | |
5979 { | |
5980 if (*p != TAB && needclr) | |
5981 { | |
5982 // remove any text still there from the command | |
5983 msg_clr_eos(); | |
5984 needclr = FALSE; | |
5985 } | |
5986 msg_putchar_attr(*p, echo_attr); | |
5987 } | |
5988 else | |
5989 { | |
5990 if (has_mbyte) | |
5991 { | |
5992 int i = (*mb_ptr2len)(p); | |
5993 | |
5994 (void)msg_outtrans_len_attr(p, i, echo_attr); | |
5995 p += i - 1; | |
5996 } | |
5997 else | |
5998 (void)msg_outtrans_len_attr(p, 1, echo_attr); | |
5999 } | |
6000 } | |
6001 vim_free(tofree); | |
6002 } | |
6003 clear_tv(&rettv); | 6071 clear_tv(&rettv); |
6004 arg = skipwhite(arg); | 6072 arg = skipwhite(arg); |
6005 } | 6073 } |
6006 eap->nextcmd = check_nextcmd(arg); | 6074 eap->nextcmd = check_nextcmd(arg); |
6007 | 6075 |
6367 case EXPR_GEQUAL: n1 = (f1 >= f2); break; | 6435 case EXPR_GEQUAL: n1 = (f1 >= f2); break; |
6368 case EXPR_SMALLER: n1 = (f1 < f2); break; | 6436 case EXPR_SMALLER: n1 = (f1 < f2); break; |
6369 case EXPR_SEQUAL: n1 = (f1 <= f2); break; | 6437 case EXPR_SEQUAL: n1 = (f1 <= f2); break; |
6370 case EXPR_UNKNOWN: | 6438 case EXPR_UNKNOWN: |
6371 case EXPR_MATCH: | 6439 case EXPR_MATCH: |
6372 case EXPR_NOMATCH: break; // avoid gcc warning | 6440 default: break; // avoid gcc warning |
6373 } | 6441 } |
6374 } | 6442 } |
6375 #endif | 6443 #endif |
6376 | 6444 |
6377 /* | 6445 /* |
6393 case EXPR_GEQUAL: n1 = (n1 >= n2); break; | 6461 case EXPR_GEQUAL: n1 = (n1 >= n2); break; |
6394 case EXPR_SMALLER: n1 = (n1 < n2); break; | 6462 case EXPR_SMALLER: n1 = (n1 < n2); break; |
6395 case EXPR_SEQUAL: n1 = (n1 <= n2); break; | 6463 case EXPR_SEQUAL: n1 = (n1 <= n2); break; |
6396 case EXPR_UNKNOWN: | 6464 case EXPR_UNKNOWN: |
6397 case EXPR_MATCH: | 6465 case EXPR_MATCH: |
6398 case EXPR_NOMATCH: break; // avoid gcc warning | 6466 default: break; // avoid gcc warning |
6399 } | 6467 } |
6400 } | 6468 } |
6401 else | 6469 else |
6402 { | 6470 { |
6403 s1 = tv_get_string_buf(typ1, buf1); | 6471 s1 = tv_get_string_buf(typ1, buf1); |
6423 n1 = pattern_match(s2, s1, ic); | 6491 n1 = pattern_match(s2, s1, ic); |
6424 if (type == EXPR_NOMATCH) | 6492 if (type == EXPR_NOMATCH) |
6425 n1 = !n1; | 6493 n1 = !n1; |
6426 break; | 6494 break; |
6427 | 6495 |
6428 case EXPR_UNKNOWN: break; // avoid gcc warning | 6496 default: break; // avoid gcc warning |
6429 } | 6497 } |
6430 } | 6498 } |
6431 clear_tv(typ1); | 6499 clear_tv(typ1); |
6432 typ1->v_type = VAR_NUMBER; | 6500 typ1->v_type = VAR_NUMBER; |
6433 typ1->vval.v_number = n1; | 6501 typ1->vval.v_number = n1; |