blob: 7795f41dbf044a6439c2eb148f11fb6c5fbf722e [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * eval.c: Expression evaluation.
12 */
Bram Moolenaarfefecb02016-02-27 21:27:20 +010013#define USING_FLOAT_STUFF
Bram Moolenaar071d4272004-06-13 20:20:40 +000014
15#include "vim.h"
16
Bram Moolenaar8c8de832008-06-24 22:58:06 +000017#if defined(FEAT_EVAL) || defined(PROTO)
18
Bram Moolenaar314f11d2010-08-09 22:07:08 +020019#ifdef VMS
20# include <float.h>
21#endif
22
Bram Moolenaarc70646c2005-01-04 21:52:38 +000023static char *e_missbrac = N_("E111: Missing ']'");
Bram Moolenaar9ef486d2005-01-17 22:23:00 +000024static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
Bram Moolenaar8c0e3222013-06-16 17:32:40 +020025#ifdef FEAT_FLOAT
Bram Moolenaar2a876e42013-06-12 22:08:58 +020026static char *e_float_as_string = N_("E806: using Float as a String");
Bram Moolenaar8c0e3222013-06-16 17:32:40 +020027#endif
Bram Moolenaar22a0c0c2019-08-09 23:25:08 +020028static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis");
Bram Moolenaar8c8de832008-06-24 22:58:06 +000029
Bram Moolenaar9bbf63d2016-01-16 16:49:28 +010030#define NAMESPACE_CHAR (char_u *)"abglstvw"
31
Bram Moolenaar230bb3f2013-04-24 14:07:45 +020032static dictitem_T globvars_var; /* variable used for g: */
Bram Moolenaar071d4272004-06-13 20:20:40 +000033
34/*
Bram Moolenaar532c7802005-01-27 14:44:31 +000035 * Old Vim variables such as "v:version" are also available without the "v:".
36 * Also in functions. We need a special hashtable for them.
37 */
Bram Moolenaar4debb442005-06-01 21:57:40 +000038static hashtab_T compat_hashtab;
Bram Moolenaar532c7802005-01-27 14:44:31 +000039
40/*
Bram Moolenaard9fba312005-06-26 22:34:35 +000041 * When recursively copying lists and dicts we need to remember which ones we
42 * have done to avoid endless recursiveness. This unique ID is used for that.
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +000043 * The last bit is used for previous_funccal, ignored when comparing.
Bram Moolenaard9fba312005-06-26 22:34:35 +000044 */
45static int current_copyID = 0;
Bram Moolenaar8502c702014-06-17 12:51:16 +020046
Bram Moolenaard9fba312005-06-26 22:34:35 +000047/*
Bram Moolenaar33570922005-01-25 22:26:29 +000048 * Array to hold the hashtab with variables local to each sourced script.
49 * Each item holds a variable (nameless) that points to the dict_T.
Bram Moolenaar071d4272004-06-13 20:20:40 +000050 */
Bram Moolenaar33570922005-01-25 22:26:29 +000051typedef struct
52{
53 dictitem_T sv_var;
54 dict_T sv_dict;
55} scriptvar_T;
56
Bram Moolenaar9577c3e2010-05-14 12:16:25 +020057static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
58#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
59#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
Bram Moolenaar071d4272004-06-13 20:20:40 +000060
61static int echo_attr = 0; /* attributes used for ":echo" */
62
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000063/* The names of packages that once were loaded are remembered. */
Bram Moolenaaraa35dd12006-04-29 22:03:41 +000064static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
65
Bram Moolenaar071d4272004-06-13 20:20:40 +000066/*
Bram Moolenaar3d60ec22005-01-05 22:19:46 +000067 * Info used by a ":for" loop.
68 */
Bram Moolenaar33570922005-01-25 22:26:29 +000069typedef struct
Bram Moolenaar3d60ec22005-01-05 22:19:46 +000070{
71 int fi_semicolon; /* TRUE if ending in '; var]' */
72 int fi_varcount; /* nr of variables in the list */
Bram Moolenaar33570922005-01-25 22:26:29 +000073 listwatch_T fi_lw; /* keep an eye on the item used. */
74 list_T *fi_list; /* list being used */
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +010075 int fi_bi; /* index of blob */
76 blob_T *fi_blob; /* blob being used */
Bram Moolenaar33570922005-01-25 22:26:29 +000077} forinfo_T;
Bram Moolenaar3d60ec22005-01-05 22:19:46 +000078
Bram Moolenaara7043832005-01-21 11:56:39 +000079
80/*
Bram Moolenaar33570922005-01-25 22:26:29 +000081 * Array to hold the value of v: variables.
82 * The value is in a dictitem, so that it can also be used in the v: scope.
83 * The reason to use this table anyway is for very quick access to the
84 * variables with the VV_ defines.
85 */
Bram Moolenaar33570922005-01-25 22:26:29 +000086
87/* values for vv_flags: */
88#define VV_COMPAT 1 /* compatible, also used without "v:" */
89#define VV_RO 2 /* read-only */
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +000090#define VV_RO_SBX 4 /* read-only in the sandbox */
Bram Moolenaar33570922005-01-25 22:26:29 +000091
Bram Moolenaarbee6c0c2016-03-25 15:40:50 +010092#define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}
Bram Moolenaar33570922005-01-25 22:26:29 +000093
94static struct vimvar
95{
96 char *vv_name; /* name of variable, without v: */
Bram Moolenaarbee6c0c2016-03-25 15:40:50 +010097 dictitem16_T vv_di; /* value and name for key (max 16 chars!) */
Bram Moolenaar33570922005-01-25 22:26:29 +000098 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */
99} vimvars[VV_LEN] =
100{
101 /*
102 * The order here must match the VV_ defines in vim.h!
103 * Initializing a union does not work, leave tv.vval empty to get zero's.
104 */
105 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO},
106 {VV_NAME("count1", VAR_NUMBER), VV_RO},
107 {VV_NAME("prevcount", VAR_NUMBER), VV_RO},
108 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT},
109 {VV_NAME("warningmsg", VAR_STRING), 0},
110 {VV_NAME("statusmsg", VAR_STRING), 0},
111 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO},
112 {VV_NAME("this_session", VAR_STRING), VV_COMPAT},
113 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO},
114 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX},
115 {VV_NAME("termresponse", VAR_STRING), VV_RO},
116 {VV_NAME("fname", VAR_STRING), VV_RO},
117 {VV_NAME("lang", VAR_STRING), VV_RO},
118 {VV_NAME("lc_time", VAR_STRING), VV_RO},
119 {VV_NAME("ctype", VAR_STRING), VV_RO},
120 {VV_NAME("charconvert_from", VAR_STRING), VV_RO},
121 {VV_NAME("charconvert_to", VAR_STRING), VV_RO},
122 {VV_NAME("fname_in", VAR_STRING), VV_RO},
123 {VV_NAME("fname_out", VAR_STRING), VV_RO},
124 {VV_NAME("fname_new", VAR_STRING), VV_RO},
125 {VV_NAME("fname_diff", VAR_STRING), VV_RO},
126 {VV_NAME("cmdarg", VAR_STRING), VV_RO},
127 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX},
128 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX},
129 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX},
130 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX},
131 {VV_NAME("progname", VAR_STRING), VV_RO},
132 {VV_NAME("servername", VAR_STRING), VV_RO},
133 {VV_NAME("dying", VAR_NUMBER), VV_RO},
134 {VV_NAME("exception", VAR_STRING), VV_RO},
135 {VV_NAME("throwpoint", VAR_STRING), VV_RO},
136 {VV_NAME("register", VAR_STRING), VV_RO},
137 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO},
138 {VV_NAME("insertmode", VAR_STRING), VV_RO},
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +0000139 {VV_NAME("val", VAR_UNKNOWN), VV_RO},
140 {VV_NAME("key", VAR_UNKNOWN), VV_RO},
Bram Moolenaar05159a02005-02-26 23:04:13 +0000141 {VV_NAME("profiling", VAR_NUMBER), VV_RO},
Bram Moolenaar19a09a12005-03-04 23:39:37 +0000142 {VV_NAME("fcs_reason", VAR_STRING), VV_RO},
143 {VV_NAME("fcs_choice", VAR_STRING), 0},
Bram Moolenaare2ac10d2005-03-07 23:26:06 +0000144 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO},
145 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO},
Bram Moolenaarc9721bd2016-06-04 17:41:03 +0200146 {VV_NAME("beval_winid", VAR_NUMBER), VV_RO},
Bram Moolenaare2ac10d2005-03-07 23:26:06 +0000147 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO},
148 {VV_NAME("beval_col", VAR_NUMBER), VV_RO},
149 {VV_NAME("beval_text", VAR_STRING), VV_RO},
Bram Moolenaar761b1132005-10-03 22:05:45 +0000150 {VV_NAME("scrollstart", VAR_STRING), 0},
Bram Moolenaard5bc83f2005-12-07 21:07:59 +0000151 {VV_NAME("swapname", VAR_STRING), VV_RO},
152 {VV_NAME("swapchoice", VAR_STRING), 0},
Bram Moolenaar63a121b2005-12-11 21:36:39 +0000153 {VV_NAME("swapcommand", VAR_STRING), VV_RO},
Bram Moolenaare659c952011-05-19 17:25:41 +0200154 {VV_NAME("char", VAR_STRING), 0},
Bram Moolenaar219b8702006-11-01 14:32:36 +0000155 {VV_NAME("mouse_win", VAR_NUMBER), 0},
Bram Moolenaar511972d2016-06-04 18:09:59 +0200156 {VV_NAME("mouse_winid", VAR_NUMBER), 0},
Bram Moolenaar219b8702006-11-01 14:32:36 +0000157 {VV_NAME("mouse_lnum", VAR_NUMBER), 0},
158 {VV_NAME("mouse_col", VAR_NUMBER), 0},
Bram Moolenaar8af1fbf2008-01-05 12:35:21 +0000159 {VV_NAME("operator", VAR_STRING), VV_RO},
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000160 {VV_NAME("searchforward", VAR_NUMBER), 0},
Bram Moolenaar8050efa2013-11-08 04:30:20 +0100161 {VV_NAME("hlsearch", VAR_NUMBER), 0},
Bram Moolenaard812df62008-11-09 12:46:09 +0000162 {VV_NAME("oldfiles", VAR_LIST), 0},
Bram Moolenaar727c8762010-10-20 19:17:48 +0200163 {VV_NAME("windowid", VAR_NUMBER), VV_RO},
Bram Moolenaara1706c92014-04-01 19:55:49 +0200164 {VV_NAME("progpath", VAR_STRING), VV_RO},
Bram Moolenaar42a45122015-07-10 17:56:23 +0200165 {VV_NAME("completed_item", VAR_DICT), VV_RO},
Bram Moolenaar53744302015-07-17 17:38:22 +0200166 {VV_NAME("option_new", VAR_STRING), VV_RO},
167 {VV_NAME("option_old", VAR_STRING), VV_RO},
Bram Moolenaard7c96872019-06-15 17:12:48 +0200168 {VV_NAME("option_oldlocal", VAR_STRING), VV_RO},
169 {VV_NAME("option_oldglobal", VAR_STRING), VV_RO},
170 {VV_NAME("option_command", VAR_STRING), VV_RO},
Bram Moolenaar53744302015-07-17 17:38:22 +0200171 {VV_NAME("option_type", VAR_STRING), VV_RO},
Bram Moolenaar43345542015-11-29 17:35:35 +0100172 {VV_NAME("errors", VAR_LIST), 0},
Bram Moolenaar520e1e42016-01-23 19:46:28 +0100173 {VV_NAME("false", VAR_SPECIAL), VV_RO},
174 {VV_NAME("true", VAR_SPECIAL), VV_RO},
175 {VV_NAME("null", VAR_SPECIAL), VV_RO},
176 {VV_NAME("none", VAR_SPECIAL), VV_RO},
Bram Moolenaar14735512016-03-26 21:00:08 +0100177 {VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO},
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +0200178 {VV_NAME("testing", VAR_NUMBER), 0},
Bram Moolenaarf562e722016-07-19 17:25:25 +0200179 {VV_NAME("t_number", VAR_NUMBER), VV_RO},
180 {VV_NAME("t_string", VAR_NUMBER), VV_RO},
181 {VV_NAME("t_func", VAR_NUMBER), VV_RO},
182 {VV_NAME("t_list", VAR_NUMBER), VV_RO},
183 {VV_NAME("t_dict", VAR_NUMBER), VV_RO},
184 {VV_NAME("t_float", VAR_NUMBER), VV_RO},
185 {VV_NAME("t_bool", VAR_NUMBER), VV_RO},
186 {VV_NAME("t_none", VAR_NUMBER), VV_RO},
187 {VV_NAME("t_job", VAR_NUMBER), VV_RO},
188 {VV_NAME("t_channel", VAR_NUMBER), VV_RO},
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +0100189 {VV_NAME("t_blob", VAR_NUMBER), VV_RO},
Bram Moolenaar65e4c4f2017-10-14 23:24:25 +0200190 {VV_NAME("termrfgresp", VAR_STRING), VV_RO},
191 {VV_NAME("termrbgresp", VAR_STRING), VV_RO},
Bram Moolenaarf3af54e2017-08-30 14:53:06 +0200192 {VV_NAME("termu7resp", VAR_STRING), VV_RO},
Bram Moolenaar37df9a42019-06-14 14:39:51 +0200193 {VV_NAME("termstyleresp", VAR_STRING), VV_RO},
194 {VV_NAME("termblinkresp", VAR_STRING), VV_RO},
195 {VV_NAME("event", VAR_DICT), VV_RO},
196 {VV_NAME("versionlong", VAR_NUMBER), VV_RO},
Bram Moolenaar37f4cbd2019-08-23 20:58:45 +0200197 {VV_NAME("echospace", VAR_NUMBER), VV_RO},
Bram Moolenaar33570922005-01-25 22:26:29 +0000198};
199
200/* shorthand */
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000201#define vv_type vv_di.di_tv.v_type
202#define vv_nr vv_di.di_tv.vval.v_number
203#define vv_float vv_di.di_tv.vval.v_float
204#define vv_str vv_di.di_tv.vval.v_string
Bram Moolenaard812df62008-11-09 12:46:09 +0000205#define vv_list vv_di.di_tv.vval.v_list
Bram Moolenaar42a45122015-07-10 17:56:23 +0200206#define vv_dict vv_di.di_tv.vval.v_dict
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +0100207#define vv_blob vv_di.di_tv.vval.v_blob
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000208#define vv_tv vv_di.di_tv
Bram Moolenaar33570922005-01-25 22:26:29 +0000209
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200210static dictitem_T vimvars_var; /* variable used for v: */
Bram Moolenaar33570922005-01-25 22:26:29 +0000211#define vimvarht vimvardict.dv_hashtab
212
Bram Moolenaar48e697e2016-01-23 22:17:30 +0100213static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op);
Bram Moolenaar48e697e2016-01-23 22:17:30 +0100214static int eval2(char_u **arg, typval_T *rettv, int evaluate);
215static int eval3(char_u **arg, typval_T *rettv, int evaluate);
216static int eval4(char_u **arg, typval_T *rettv, int evaluate);
217static int eval5(char_u **arg, typval_T *rettv, int evaluate);
218static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string);
219static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string);
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +0200220static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp);
Bram Moolenaara40058a2005-07-11 22:42:07 +0000221
Bram Moolenaar48e697e2016-01-23 22:17:30 +0100222static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate);
223static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate);
Bram Moolenaar48e697e2016-01-23 22:17:30 +0100224static int free_unref_items(int copyID);
Bram Moolenaar48e697e2016-01-23 22:17:30 +0100225static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
Bram Moolenaar5843f5f2019-08-20 20:13:45 +0200226static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +0200227static void check_vars(char_u *name, int len);
Bram Moolenaar48e697e2016-01-23 22:17:30 +0100228static typval_T *alloc_string_tv(char_u *string);
Bram Moolenaar05c00c02019-02-11 22:00:11 +0100229static int tv_check_lock(typval_T *tv, char_u *name, int use_gettext);
Bram Moolenaar2c704a72010-06-03 21:17:25 +0200230
Bram Moolenaar73dad1e2016-07-17 22:13:49 +0200231/* for VIM_VERSION_ defines */
232#include "version.h"
233
Bram Moolenaare21c1582019-03-02 11:57:09 +0100234/*
235 * Return "n1" divided by "n2", taking care of dividing by zero.
236 */
Bram Moolenaar0522ba02019-08-27 22:48:30 +0200237 varnumber_T
Bram Moolenaare21c1582019-03-02 11:57:09 +0100238num_divide(varnumber_T n1, varnumber_T n2)
239{
240 varnumber_T result;
241
242 if (n2 == 0) // give an error message?
243 {
244 if (n1 == 0)
245 result = VARNUM_MIN; // similar to NaN
246 else if (n1 < 0)
247 result = -VARNUM_MAX;
248 else
249 result = VARNUM_MAX;
250 }
251 else
252 result = n1 / n2;
253
254 return result;
255}
256
257/*
258 * Return "n1" modulus "n2", taking care of dividing by zero.
259 */
Bram Moolenaar0522ba02019-08-27 22:48:30 +0200260 varnumber_T
Bram Moolenaare21c1582019-03-02 11:57:09 +0100261num_modulus(varnumber_T n1, varnumber_T n2)
262{
263 // Give an error when n2 is 0?
264 return (n2 == 0) ? 0 : (n1 % n2);
265}
266
Bram Moolenaara1fa8922017-01-12 20:06:33 +0100267
268#if defined(EBCDIC) || defined(PROTO)
269/*
270 * Compare struct fst by function name.
271 */
272 static int
273compare_func_name(const void *s1, const void *s2)
274{
275 struct fst *p1 = (struct fst *)s1;
276 struct fst *p2 = (struct fst *)s2;
277
278 return STRCMP(p1->f_name, p2->f_name);
279}
280
281/*
282 * Sort the function table by function name.
Bram Moolenaarb5443cc2019-01-15 20:19:40 +0100283 * The sorting of the table above is ASCII dependent.
Bram Moolenaara1fa8922017-01-12 20:06:33 +0100284 * On machines using EBCDIC we have to sort it.
285 */
286 static void
287sortFunctions(void)
288{
289 int funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
290
291 qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name);
292}
293#endif
294
295
Bram Moolenaar33570922005-01-25 22:26:29 +0000296/*
297 * Initialize the global and v: variables.
Bram Moolenaara7043832005-01-21 11:56:39 +0000298 */
299 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100300eval_init(void)
Bram Moolenaara7043832005-01-21 11:56:39 +0000301{
Bram Moolenaar33570922005-01-25 22:26:29 +0000302 int i;
303 struct vimvar *p;
304
Bram Moolenaarbdb62052012-07-16 17:31:53 +0200305 init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE);
306 init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE);
Bram Moolenaar32f649e2011-04-11 13:46:13 +0200307 vimvardict.dv_lock = VAR_FIXED;
Bram Moolenaar532c7802005-01-27 14:44:31 +0000308 hash_init(&compat_hashtab);
Bram Moolenaara9b579f2016-07-17 18:29:19 +0200309 func_init();
Bram Moolenaar33570922005-01-25 22:26:29 +0000310
311 for (i = 0; i < VV_LEN; ++i)
312 {
313 p = &vimvars[i];
Bram Moolenaard7c96872019-06-15 17:12:48 +0200314 if (STRLEN(p->vv_name) > DICTITEM16_KEY_LEN)
Bram Moolenaaref9d9b92016-03-28 22:44:50 +0200315 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100316 iemsg("INTERNAL: name too long, increase size of dictitem16_T");
Bram Moolenaaref9d9b92016-03-28 22:44:50 +0200317 getout(1);
318 }
Bram Moolenaar33570922005-01-25 22:26:29 +0000319 STRCPY(p->vv_di.di_key, p->vv_name);
320 if (p->vv_flags & VV_RO)
321 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
322 else if (p->vv_flags & VV_RO_SBX)
323 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX;
324 else
325 p->vv_di.di_flags = DI_FLAGS_FIX;
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +0000326
327 /* add to v: scope dict, unless the value is not always available */
328 if (p->vv_type != VAR_UNKNOWN)
329 hash_add(&vimvarht, p->vv_di.di_key);
Bram Moolenaar33570922005-01-25 22:26:29 +0000330 if (p->vv_flags & VV_COMPAT)
Bram Moolenaar532c7802005-01-27 14:44:31 +0000331 /* add to compat scope dict */
332 hash_add(&compat_hashtab, p->vv_di.di_key);
Bram Moolenaar33570922005-01-25 22:26:29 +0000333 }
Bram Moolenaara542c682016-01-31 16:28:04 +0100334 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
Bram Moolenaar37df9a42019-06-14 14:39:51 +0200335 vimvars[VV_VERSIONLONG].vv_nr = VIM_VERSION_100 * 10000 + highest_patch();
Bram Moolenaara542c682016-01-31 16:28:04 +0100336
Bram Moolenaar8c8de832008-06-24 22:58:06 +0000337 set_vim_var_nr(VV_SEARCHFORWARD, 1L);
Bram Moolenaar8050efa2013-11-08 04:30:20 +0100338 set_vim_var_nr(VV_HLSEARCH, 1L);
Bram Moolenaar7e1652c2017-12-16 18:27:02 +0100339 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
Bram Moolenaar4649ded2015-12-03 14:55:55 +0100340 set_vim_var_list(VV_ERRORS, list_alloc());
Bram Moolenaar7e1652c2017-12-16 18:27:02 +0100341 set_vim_var_dict(VV_EVENT, dict_alloc_lock(VAR_FIXED));
Bram Moolenaar520e1e42016-01-23 19:46:28 +0100342
343 set_vim_var_nr(VV_FALSE, VVAL_FALSE);
344 set_vim_var_nr(VV_TRUE, VVAL_TRUE);
345 set_vim_var_nr(VV_NONE, VVAL_NONE);
346 set_vim_var_nr(VV_NULL, VVAL_NULL);
347
Bram Moolenaarf562e722016-07-19 17:25:25 +0200348 set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER);
349 set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING);
350 set_vim_var_nr(VV_TYPE_FUNC, VAR_TYPE_FUNC);
351 set_vim_var_nr(VV_TYPE_LIST, VAR_TYPE_LIST);
352 set_vim_var_nr(VV_TYPE_DICT, VAR_TYPE_DICT);
353 set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT);
354 set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL);
355 set_vim_var_nr(VV_TYPE_NONE, VAR_TYPE_NONE);
356 set_vim_var_nr(VV_TYPE_JOB, VAR_TYPE_JOB);
357 set_vim_var_nr(VV_TYPE_CHANNEL, VAR_TYPE_CHANNEL);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +0100358 set_vim_var_nr(VV_TYPE_BLOB, VAR_TYPE_BLOB);
Bram Moolenaarf562e722016-07-19 17:25:25 +0200359
Bram Moolenaar37f4cbd2019-08-23 20:58:45 +0200360 set_vim_var_nr(VV_ECHOSPACE, sc_col - 1);
361
Bram Moolenaarb429cde2012-04-25 18:24:29 +0200362 set_reg_var(0); /* default for v:register is not 0 but '"' */
Bram Moolenaar2c704a72010-06-03 21:17:25 +0200363
364#ifdef EBCDIC
365 /*
Bram Moolenaar195ea0f2011-11-30 14:57:31 +0100366 * Sort the function table, to enable binary search.
Bram Moolenaar2c704a72010-06-03 21:17:25 +0200367 */
368 sortFunctions();
369#endif
Bram Moolenaara7043832005-01-21 11:56:39 +0000370}
371
Bram Moolenaar29a1c1d2005-06-24 23:11:15 +0000372#if defined(EXITFREE) || defined(PROTO)
373 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100374eval_clear(void)
Bram Moolenaar29a1c1d2005-06-24 23:11:15 +0000375{
376 int i;
377 struct vimvar *p;
378
379 for (i = 0; i < VV_LEN; ++i)
380 {
381 p = &vimvars[i];
382 if (p->vv_di.di_tv.v_type == VAR_STRING)
Bram Moolenaard23a8232018-02-10 18:45:26 +0100383 VIM_CLEAR(p->vv_str);
Bram Moolenaard812df62008-11-09 12:46:09 +0000384 else if (p->vv_di.di_tv.v_type == VAR_LIST)
385 {
386 list_unref(p->vv_list);
387 p->vv_list = NULL;
Bram Moolenaard9fba312005-06-26 22:34:35 +0000388 }
Bram Moolenaar29a1c1d2005-06-24 23:11:15 +0000389 }
390 hash_clear(&vimvarht);
Bram Moolenaar0f71c6d2008-11-12 14:29:28 +0000391 hash_init(&vimvarht); /* garbage_collect() will access it */
Bram Moolenaar29a1c1d2005-06-24 23:11:15 +0000392 hash_clear(&compat_hashtab);
393
Bram Moolenaard9fba312005-06-26 22:34:35 +0000394 free_scriptnames();
Bram Moolenaar9b486ca2011-05-19 18:26:40 +0200395 free_locales();
Bram Moolenaar29a1c1d2005-06-24 23:11:15 +0000396
397 /* global variables */
398 vars_clear(&globvarht);
Bram Moolenaard9fba312005-06-26 22:34:35 +0000399
Bram Moolenaaraa35dd12006-04-29 22:03:41 +0000400 /* autoloaded script names */
401 ga_clear_strings(&ga_loaded);
402
Bram Moolenaarcca74132013-09-25 21:00:28 +0200403 /* Script-local variables. First clear all the variables and in a second
404 * loop free the scriptvar_T, because a variable in one script might hold
405 * a reference to the whole scope of another script. */
Bram Moolenaar9577c3e2010-05-14 12:16:25 +0200406 for (i = 1; i <= ga_scripts.ga_len; ++i)
Bram Moolenaar9577c3e2010-05-14 12:16:25 +0200407 vars_clear(&SCRIPT_VARS(i));
Bram Moolenaarcca74132013-09-25 21:00:28 +0200408 for (i = 1; i <= ga_scripts.ga_len; ++i)
Bram Moolenaar9577c3e2010-05-14 12:16:25 +0200409 vim_free(SCRIPT_SV(i));
Bram Moolenaar9577c3e2010-05-14 12:16:25 +0200410 ga_clear(&ga_scripts);
411
Bram Moolenaar75ee5442019-06-06 18:05:25 +0200412 // unreferenced lists and dicts
413 (void)garbage_collect(FALSE);
Bram Moolenaarc07f67a2019-06-06 19:03:17 +0200414
415 // functions not garbage collected
416 free_all_functions();
Bram Moolenaar29a1c1d2005-06-24 23:11:15 +0000417}
418#endif
419
Bram Moolenaar071d4272004-06-13 20:20:40 +0000420
421/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000422 * Set an internal variable to a string value. Creates the variable if it does
423 * not already exist.
424 */
425 void
Bram Moolenaarb7604cc2016-01-15 21:23:22 +0100426set_internal_string_var(char_u *name, char_u *value)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000427{
Bram Moolenaar49cd9572005-01-03 21:06:01 +0000428 char_u *val;
Bram Moolenaar33570922005-01-25 22:26:29 +0000429 typval_T *tvp;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000430
431 val = vim_strsave(value);
432 if (val != NULL)
433 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000434 tvp = alloc_string_tv(val);
Bram Moolenaar49cd9572005-01-03 21:06:01 +0000435 if (tvp != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000436 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +0000437 set_var(name, tvp, FALSE);
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000438 free_tv(tvp);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000439 }
440 }
441}
442
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000443static lval_T *redir_lval = NULL;
Bram Moolenaar1e5e1232016-07-07 17:33:02 +0200444#define EVALCMD_BUSY (redir_lval == (lval_T *)&redir_lval)
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000445static garray_T redir_ga; /* only valid when redir_lval is not NULL */
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000446static char_u *redir_endp = NULL;
447static char_u *redir_varname = NULL;
448
449/*
450 * Start recording command output to a variable
Bram Moolenaarb7604cc2016-01-15 21:23:22 +0100451 * When "append" is TRUE append to an existing variable.
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000452 * Returns OK if successfully completed the setup. FAIL otherwise.
453 */
454 int
Bram Moolenaarb7604cc2016-01-15 21:23:22 +0100455var_redir_start(char_u *name, int append)
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000456{
457 int save_emsg;
458 int err;
459 typval_T tv;
460
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000461 /* Catch a bad name early. */
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +0000462 if (!eval_isnamec1(*name))
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000463 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100464 emsg(_(e_invarg));
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000465 return FAIL;
466 }
467
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000468 /* Make a copy of the name, it is used in redir_lval until redir ends. */
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000469 redir_varname = vim_strsave(name);
470 if (redir_varname == NULL)
471 return FAIL;
472
Bram Moolenaarc799fe22019-05-28 23:08:19 +0200473 redir_lval = ALLOC_CLEAR_ONE(lval_T);
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000474 if (redir_lval == NULL)
475 {
476 var_redir_stop();
477 return FAIL;
478 }
479
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000480 /* The output is stored in growarray "redir_ga" until redirection ends. */
481 ga_init2(&redir_ga, (int)sizeof(char), 500);
482
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000483 /* Parse the variable name (can be a dict or list entry). */
Bram Moolenaar6d977d62014-01-14 15:24:39 +0100484 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +0000485 FNE_CHECK_START);
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000486 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
487 {
Bram Moolenaar1dba0fb2010-07-28 18:55:02 +0200488 clear_lval(redir_lval);
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000489 if (redir_endp != NULL && *redir_endp != NUL)
490 /* Trailing characters are present after the variable name */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100491 emsg(_(e_trailing));
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000492 else
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100493 emsg(_(e_invarg));
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000494 redir_endp = NULL; /* don't store a value, only cleanup */
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000495 var_redir_stop();
496 return FAIL;
497 }
498
499 /* check if we can write to the variable: set it to or append an empty
500 * string */
501 save_emsg = did_emsg;
502 did_emsg = FALSE;
503 tv.v_type = VAR_STRING;
504 tv.vval.v_string = (char_u *)"";
505 if (append)
Bram Moolenaar9937a052019-06-15 15:45:06 +0200506 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)".");
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000507 else
Bram Moolenaar9937a052019-06-15 15:45:06 +0200508 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"=");
Bram Moolenaar1dba0fb2010-07-28 18:55:02 +0200509 clear_lval(redir_lval);
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000510 err = did_emsg;
Bram Moolenaar1f35bf92006-03-07 22:38:47 +0000511 did_emsg |= save_emsg;
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000512 if (err)
513 {
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000514 redir_endp = NULL; /* don't store a value, only cleanup */
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000515 var_redir_stop();
516 return FAIL;
517 }
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000518
519 return OK;
520}
521
522/*
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000523 * Append "value[value_len]" to the variable set by var_redir_start().
524 * The actual appending is postponed until redirection ends, because the value
525 * appended may in fact be the string we write to, changing it may cause freed
526 * memory to be used:
527 * :redir => foo
528 * :let foo
529 * :redir END
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000530 */
531 void
Bram Moolenaarb7604cc2016-01-15 21:23:22 +0100532var_redir_str(char_u *value, int value_len)
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000533{
Bram Moolenaar5fdec472007-07-24 08:45:13 +0000534 int len;
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000535
536 if (redir_lval == NULL)
537 return;
538
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000539 if (value_len == -1)
Bram Moolenaar5fdec472007-07-24 08:45:13 +0000540 len = (int)STRLEN(value); /* Append the entire string */
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000541 else
Bram Moolenaar5fdec472007-07-24 08:45:13 +0000542 len = value_len; /* Append only "value_len" characters */
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000543
Bram Moolenaar5fdec472007-07-24 08:45:13 +0000544 if (ga_grow(&redir_ga, len) == OK)
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000545 {
546 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
Bram Moolenaar5fdec472007-07-24 08:45:13 +0000547 redir_ga.ga_len += len;
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000548 }
549 else
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000550 var_redir_stop();
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000551}
552
553/*
554 * Stop redirecting command output to a variable.
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000555 * Frees the allocated memory.
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000556 */
557 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100558var_redir_stop(void)
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000559{
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000560 typval_T tv;
561
Bram Moolenaar1e5e1232016-07-07 17:33:02 +0200562 if (EVALCMD_BUSY)
563 {
564 redir_lval = NULL;
565 return;
566 }
567
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000568 if (redir_lval != NULL)
569 {
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000570 /* If there was no error: assign the text to the variable. */
571 if (redir_endp != NULL)
572 {
573 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */
574 tv.v_type = VAR_STRING;
575 tv.vval.v_string = redir_ga.ga_data;
Bram Moolenaar1dba0fb2010-07-28 18:55:02 +0200576 /* Call get_lval() again, if it's inside a Dict or List it may
577 * have changed. */
578 redir_endp = get_lval(redir_varname, NULL, redir_lval,
Bram Moolenaar6d977d62014-01-14 15:24:39 +0100579 FALSE, FALSE, 0, FNE_CHECK_START);
Bram Moolenaar1dba0fb2010-07-28 18:55:02 +0200580 if (redir_endp != NULL && redir_lval->ll_name != NULL)
Bram Moolenaar9937a052019-06-15 15:45:06 +0200581 set_var_lval(redir_lval, redir_endp, &tv, FALSE, FALSE,
582 (char_u *)".");
Bram Moolenaar1dba0fb2010-07-28 18:55:02 +0200583 clear_lval(redir_lval);
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000584 }
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000585
Bram Moolenaar2f59b5c2009-11-03 13:26:55 +0000586 /* free the collected output */
Bram Moolenaard23a8232018-02-10 18:45:26 +0100587 VIM_CLEAR(redir_ga.ga_data);
Bram Moolenaar863b53b2007-01-14 14:28:34 +0000588
Bram Moolenaard23a8232018-02-10 18:45:26 +0100589 VIM_CLEAR(redir_lval);
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000590 }
Bram Moolenaard23a8232018-02-10 18:45:26 +0100591 VIM_CLEAR(redir_varname);
Bram Moolenaar5313dcb2005-02-22 08:56:13 +0000592}
593
Bram Moolenaar071d4272004-06-13 20:20:40 +0000594 int
Bram Moolenaarb7604cc2016-01-15 21:23:22 +0100595eval_charconvert(
596 char_u *enc_from,
597 char_u *enc_to,
598 char_u *fname_from,
599 char_u *fname_to)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000600{
601 int err = FALSE;
602
603 set_vim_var_string(VV_CC_FROM, enc_from, -1);
604 set_vim_var_string(VV_CC_TO, enc_to, -1);
605 set_vim_var_string(VV_FNAME_IN, fname_from, -1);
606 set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
607 if (eval_to_bool(p_ccv, &err, NULL, FALSE))
608 err = TRUE;
609 set_vim_var_string(VV_CC_FROM, NULL, -1);
610 set_vim_var_string(VV_CC_TO, NULL, -1);
611 set_vim_var_string(VV_FNAME_IN, NULL, -1);
612 set_vim_var_string(VV_FNAME_OUT, NULL, -1);
613
614 if (err)
615 return FAIL;
616 return OK;
617}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000618
619# if defined(FEAT_POSTSCRIPT) || defined(PROTO)
620 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100621eval_printexpr(char_u *fname, char_u *args)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000622{
623 int err = FALSE;
624
625 set_vim_var_string(VV_FNAME_IN, fname, -1);
626 set_vim_var_string(VV_CMDARG, args, -1);
627 if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
628 err = TRUE;
629 set_vim_var_string(VV_FNAME_IN, NULL, -1);
630 set_vim_var_string(VV_CMDARG, NULL, -1);
631
632 if (err)
633 {
634 mch_remove(fname);
635 return FAIL;
636 }
637 return OK;
638}
639# endif
640
641# if defined(FEAT_DIFF) || defined(PROTO)
642 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100643eval_diff(
644 char_u *origfile,
645 char_u *newfile,
646 char_u *outfile)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000647{
648 int err = FALSE;
649
650 set_vim_var_string(VV_FNAME_IN, origfile, -1);
651 set_vim_var_string(VV_FNAME_NEW, newfile, -1);
652 set_vim_var_string(VV_FNAME_OUT, outfile, -1);
653 (void)eval_to_bool(p_dex, &err, NULL, FALSE);
654 set_vim_var_string(VV_FNAME_IN, NULL, -1);
655 set_vim_var_string(VV_FNAME_NEW, NULL, -1);
656 set_vim_var_string(VV_FNAME_OUT, NULL, -1);
657}
658
659 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100660eval_patch(
661 char_u *origfile,
662 char_u *difffile,
663 char_u *outfile)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000664{
665 int err;
666
667 set_vim_var_string(VV_FNAME_IN, origfile, -1);
668 set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
669 set_vim_var_string(VV_FNAME_OUT, outfile, -1);
670 (void)eval_to_bool(p_pex, &err, NULL, FALSE);
671 set_vim_var_string(VV_FNAME_IN, NULL, -1);
672 set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
673 set_vim_var_string(VV_FNAME_OUT, NULL, -1);
674}
675# endif
676
677/*
678 * Top level evaluation function, returning a boolean.
679 * Sets "error" to TRUE if there was an error.
680 * Return TRUE or FALSE.
681 */
682 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100683eval_to_bool(
684 char_u *arg,
685 int *error,
686 char_u **nextcmd,
687 int skip) /* only parse, don't execute */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000688{
Bram Moolenaar33570922005-01-25 22:26:29 +0000689 typval_T tv;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +0200690 varnumber_T retval = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000691
692 if (skip)
693 ++emsg_skip;
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000694 if (eval0(arg, &tv, nextcmd, !skip) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000695 *error = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000696 else
697 {
698 *error = FALSE;
699 if (!skip)
700 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +0100701 retval = (tv_get_number_chk(&tv, error) != 0);
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000702 clear_tv(&tv);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000703 }
704 }
705 if (skip)
706 --emsg_skip;
707
Bram Moolenaar22fcfad2016-07-01 18:17:26 +0200708 return (int)retval;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000709}
710
Bram Moolenaarce9d50d2019-01-14 22:22:29 +0100711/*
712 * Call eval1() and give an error message if not done at a lower level.
713 */
714 static int
715eval1_emsg(char_u **arg, typval_T *rettv, int evaluate)
716{
Bram Moolenaar6acc79f2019-01-14 22:53:31 +0100717 char_u *start = *arg;
Bram Moolenaarce9d50d2019-01-14 22:22:29 +0100718 int ret;
719 int did_emsg_before = did_emsg;
720 int called_emsg_before = called_emsg;
721
722 ret = eval1(arg, rettv, evaluate);
723 if (ret == FAIL)
724 {
725 // Report the invalid expression unless the expression evaluation has
726 // been cancelled due to an aborting error, an interrupt, or an
727 // exception, or we already gave a more specific error.
728 // Also check called_emsg for when using assert_fails().
729 if (!aborting() && did_emsg == did_emsg_before
730 && called_emsg == called_emsg_before)
Bram Moolenaar6acc79f2019-01-14 22:53:31 +0100731 semsg(_(e_invexpr2), start);
Bram Moolenaarce9d50d2019-01-14 22:22:29 +0100732 }
733 return ret;
734}
735
Bram Moolenaar543c9b12019-04-05 22:50:40 +0200736 int
Bram Moolenaar48570482017-10-30 21:48:41 +0100737eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
738{
739 char_u *s;
Bram Moolenaar48570482017-10-30 21:48:41 +0100740 char_u buf[NUMBUFLEN];
Bram Moolenaarc6538bc2019-08-03 18:17:11 +0200741 funcexe_T funcexe;
Bram Moolenaar48570482017-10-30 21:48:41 +0100742
743 if (expr->v_type == VAR_FUNC)
744 {
745 s = expr->vval.v_string;
746 if (s == NULL || *s == NUL)
747 return FAIL;
Bram Moolenaarc6538bc2019-08-03 18:17:11 +0200748 vim_memset(&funcexe, 0, sizeof(funcexe));
749 funcexe.evaluate = TRUE;
750 if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL)
Bram Moolenaar48570482017-10-30 21:48:41 +0100751 return FAIL;
752 }
753 else if (expr->v_type == VAR_PARTIAL)
754 {
755 partial_T *partial = expr->vval.v_partial;
756
757 s = partial_name(partial);
758 if (s == NULL || *s == NUL)
759 return FAIL;
Bram Moolenaarc6538bc2019-08-03 18:17:11 +0200760 vim_memset(&funcexe, 0, sizeof(funcexe));
761 funcexe.evaluate = TRUE;
762 funcexe.partial = partial;
763 if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL)
Bram Moolenaar48570482017-10-30 21:48:41 +0100764 return FAIL;
765 }
766 else
767 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +0100768 s = tv_get_string_buf_chk(expr, buf);
Bram Moolenaar48570482017-10-30 21:48:41 +0100769 if (s == NULL)
770 return FAIL;
771 s = skipwhite(s);
Bram Moolenaarce9d50d2019-01-14 22:22:29 +0100772 if (eval1_emsg(&s, rettv, TRUE) == FAIL)
Bram Moolenaar48570482017-10-30 21:48:41 +0100773 return FAIL;
774 if (*s != NUL) /* check for trailing chars after expr */
775 {
Bram Moolenaara43ebe92018-07-14 17:25:01 +0200776 clear_tv(rettv);
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100777 semsg(_(e_invexpr2), s);
Bram Moolenaar48570482017-10-30 21:48:41 +0100778 return FAIL;
779 }
780 }
781 return OK;
782}
783
784/*
785 * Like eval_to_bool() but using a typval_T instead of a string.
786 * Works for string, funcref and partial.
787 */
788 int
789eval_expr_to_bool(typval_T *expr, int *error)
790{
791 typval_T rettv;
792 int res;
793
794 if (eval_expr_typval(expr, NULL, 0, &rettv) == FAIL)
795 {
796 *error = TRUE;
797 return FALSE;
798 }
Bram Moolenaard155d7a2018-12-21 16:04:21 +0100799 res = (tv_get_number_chk(&rettv, error) != 0);
Bram Moolenaar48570482017-10-30 21:48:41 +0100800 clear_tv(&rettv);
801 return res;
802}
803
Bram Moolenaar071d4272004-06-13 20:20:40 +0000804/*
805 * Top level evaluation function, returning a string. If "skip" is TRUE,
806 * only parsing to "nextcmd" is done, without reporting errors. Return
807 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
808 */
809 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +0100810eval_to_string_skip(
811 char_u *arg,
812 char_u **nextcmd,
813 int skip) /* only parse, don't execute */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000814{
Bram Moolenaar33570922005-01-25 22:26:29 +0000815 typval_T tv;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000816 char_u *retval;
817
818 if (skip)
819 ++emsg_skip;
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000820 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000821 retval = NULL;
822 else
823 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +0100824 retval = vim_strsave(tv_get_string(&tv));
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000825 clear_tv(&tv);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000826 }
827 if (skip)
828 --emsg_skip;
829
830 return retval;
831}
832
833/*
Bram Moolenaar69a7cb42004-06-20 12:51:53 +0000834 * Skip over an expression at "*pp".
835 * Return FAIL for an error, OK otherwise.
836 */
837 int
Bram Moolenaar7454a062016-01-30 15:14:10 +0100838skip_expr(char_u **pp)
Bram Moolenaar69a7cb42004-06-20 12:51:53 +0000839{
Bram Moolenaar33570922005-01-25 22:26:29 +0000840 typval_T rettv;
Bram Moolenaar69a7cb42004-06-20 12:51:53 +0000841
842 *pp = skipwhite(*pp);
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000843 return eval1(pp, &rettv, FALSE);
Bram Moolenaar69a7cb42004-06-20 12:51:53 +0000844}
845
846/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000847 * Top level evaluation function, returning a string.
Bram Moolenaara85fb752008-09-07 11:55:43 +0000848 * When "convert" is TRUE convert a List into a sequence of lines and convert
849 * a Float to a String.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000850 * Return pointer to allocated memory, or NULL for failure.
851 */
852 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +0100853eval_to_string(
854 char_u *arg,
855 char_u **nextcmd,
856 int convert)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000857{
Bram Moolenaar33570922005-01-25 22:26:29 +0000858 typval_T tv;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000859 char_u *retval;
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000860 garray_T ga;
Bram Moolenaar798b30b2009-04-22 10:56:16 +0000861#ifdef FEAT_FLOAT
Bram Moolenaara85fb752008-09-07 11:55:43 +0000862 char_u numbuf[NUMBUFLEN];
Bram Moolenaar798b30b2009-04-22 10:56:16 +0000863#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000864
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000865 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000866 retval = NULL;
867 else
868 {
Bram Moolenaara85fb752008-09-07 11:55:43 +0000869 if (convert && tv.v_type == VAR_LIST)
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000870 {
871 ga_init2(&ga, (int)sizeof(char), 80);
Bram Moolenaar9bf749b2008-07-27 13:57:29 +0000872 if (tv.vval.v_list != NULL)
Bram Moolenaar213b10a2011-08-10 12:38:08 +0200873 {
Bram Moolenaar18dfb442016-05-31 22:31:23 +0200874 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, FALSE, 0);
Bram Moolenaar213b10a2011-08-10 12:38:08 +0200875 if (tv.vval.v_list->lv_len > 0)
876 ga_append(&ga, NL);
877 }
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000878 ga_append(&ga, NUL);
879 retval = (char_u *)ga.ga_data;
880 }
Bram Moolenaara85fb752008-09-07 11:55:43 +0000881#ifdef FEAT_FLOAT
882 else if (convert && tv.v_type == VAR_FLOAT)
883 {
884 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
885 retval = vim_strsave(numbuf);
886 }
887#endif
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000888 else
Bram Moolenaard155d7a2018-12-21 16:04:21 +0100889 retval = vim_strsave(tv_get_string(&tv));
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000890 clear_tv(&tv);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000891 }
892
893 return retval;
894}
895
896/*
Bram Moolenaarb71eaae2006-01-20 23:10:18 +0000897 * Call eval_to_string() without using current local variables and using
898 * textlock. When "use_sandbox" is TRUE use the sandbox.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000899 */
900 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +0100901eval_to_string_safe(
902 char_u *arg,
903 char_u **nextcmd,
904 int use_sandbox)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000905{
906 char_u *retval;
Bram Moolenaar27e80c82018-10-14 21:41:01 +0200907 funccal_entry_T funccal_entry;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000908
Bram Moolenaar27e80c82018-10-14 21:41:01 +0200909 save_funccal(&funccal_entry);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +0000910 if (use_sandbox)
911 ++sandbox;
912 ++textlock;
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000913 retval = eval_to_string(arg, nextcmd, FALSE);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +0000914 if (use_sandbox)
915 --sandbox;
916 --textlock;
Bram Moolenaar27e80c82018-10-14 21:41:01 +0200917 restore_funccal();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000918 return retval;
919}
920
Bram Moolenaar071d4272004-06-13 20:20:40 +0000921/*
922 * Top level evaluation function, returning a number.
923 * Evaluates "expr" silently.
924 * Returns -1 for an error.
925 */
Bram Moolenaar22fcfad2016-07-01 18:17:26 +0200926 varnumber_T
Bram Moolenaar7454a062016-01-30 15:14:10 +0100927eval_to_number(char_u *expr)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000928{
Bram Moolenaar33570922005-01-25 22:26:29 +0000929 typval_T rettv;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +0200930 varnumber_T retval;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +0000931 char_u *p = skipwhite(expr);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000932
933 ++emsg_off;
934
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000935 if (eval1(&p, &rettv, TRUE) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000936 retval = -1;
937 else
938 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +0100939 retval = tv_get_number_chk(&rettv, NULL);
Bram Moolenaarc70646c2005-01-04 21:52:38 +0000940 clear_tv(&rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000941 }
942 --emsg_off;
943
944 return retval;
945}
946
Bram Moolenaara40058a2005-07-11 22:42:07 +0000947/*
Bram Moolenaar0522ba02019-08-27 22:48:30 +0200948 * List Vim variables.
949 */
950 void
951list_vim_vars(int *first)
952{
953 list_hashtable_vars(&vimvarht, "v:", FALSE, first);
954}
955
956/*
957 * List script-local variables, if there is a script.
958 */
959 void
960list_script_vars(int *first)
961{
962 if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len)
963 list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid),
964 "s:", FALSE, first);
965}
966
967 int
968is_vimvarht(hashtab_T *ht)
969{
970 return ht == &vimvarht;
971}
972
973 int
974is_compatht(hashtab_T *ht)
975{
976 return ht == &compat_hashtab;
977}
978
979/*
Bram Moolenaara40058a2005-07-11 22:42:07 +0000980 * Prepare v: variable "idx" to be used.
981 * Save the current typeval in "save_tv".
982 * When not used yet add the variable to the v: hashtable.
983 */
Bram Moolenaar543c9b12019-04-05 22:50:40 +0200984 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100985prepare_vimvar(int idx, typval_T *save_tv)
Bram Moolenaara40058a2005-07-11 22:42:07 +0000986{
987 *save_tv = vimvars[idx].vv_tv;
988 if (vimvars[idx].vv_type == VAR_UNKNOWN)
989 hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
990}
991
992/*
993 * Restore v: variable "idx" to typeval "save_tv".
994 * When no longer defined, remove the variable from the v: hashtable.
995 */
Bram Moolenaar543c9b12019-04-05 22:50:40 +0200996 void
Bram Moolenaar7454a062016-01-30 15:14:10 +0100997restore_vimvar(int idx, typval_T *save_tv)
Bram Moolenaara40058a2005-07-11 22:42:07 +0000998{
999 hashitem_T *hi;
1000
Bram Moolenaara40058a2005-07-11 22:42:07 +00001001 vimvars[idx].vv_tv = *save_tv;
1002 if (vimvars[idx].vv_type == VAR_UNKNOWN)
1003 {
1004 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
1005 if (HASHITEM_EMPTY(hi))
Bram Moolenaar95f09602016-11-10 20:01:45 +01001006 internal_error("restore_vimvar()");
Bram Moolenaara40058a2005-07-11 22:42:07 +00001007 else
1008 hash_remove(&vimvarht, hi);
1009 }
1010}
1011
Bram Moolenaar3c56a962006-03-12 22:19:04 +00001012#if defined(FEAT_SPELL) || defined(PROTO)
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00001013/*
1014 * Evaluate an expression to a list with suggestions.
1015 * For the "expr:" part of 'spellsuggest'.
Bram Moolenaar9bf749b2008-07-27 13:57:29 +00001016 * Returns NULL when there is an error.
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00001017 */
1018 list_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001019eval_spell_expr(char_u *badword, char_u *expr)
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00001020{
1021 typval_T save_val;
1022 typval_T rettv;
1023 list_T *list = NULL;
1024 char_u *p = skipwhite(expr);
1025
1026 /* Set "v:val" to the bad word. */
1027 prepare_vimvar(VV_VAL, &save_val);
1028 vimvars[VV_VAL].vv_type = VAR_STRING;
1029 vimvars[VV_VAL].vv_str = badword;
1030 if (p_verbose == 0)
1031 ++emsg_off;
1032
1033 if (eval1(&p, &rettv, TRUE) == OK)
1034 {
1035 if (rettv.v_type != VAR_LIST)
1036 clear_tv(&rettv);
1037 else
1038 list = rettv.vval.v_list;
1039 }
1040
1041 if (p_verbose == 0)
1042 --emsg_off;
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00001043 restore_vimvar(VV_VAL, &save_val);
1044
1045 return list;
1046}
1047
1048/*
1049 * "list" is supposed to contain two items: a word and a number. Return the
1050 * word in "pp" and the number as the return value.
1051 * Return -1 if anything isn't right.
1052 * Used to get the good word and score from the eval_spell_expr() result.
1053 */
1054 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001055get_spellword(list_T *list, char_u **pp)
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00001056{
1057 listitem_T *li;
1058
1059 li = list->lv_first;
1060 if (li == NULL)
1061 return -1;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001062 *pp = tv_get_string(&li->li_tv);
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00001063
1064 li = li->li_next;
1065 if (li == NULL)
1066 return -1;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001067 return (int)tv_get_number(&li->li_tv);
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00001068}
1069#endif
1070
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00001071/*
Bram Moolenaar4770d092006-01-12 23:22:24 +00001072 * Top level evaluation function.
1073 * Returns an allocated typval_T with the result.
1074 * Returns NULL when there is an error.
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00001075 */
1076 typval_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001077eval_expr(char_u *arg, char_u **nextcmd)
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00001078{
1079 typval_T *tv;
1080
Bram Moolenaarc799fe22019-05-28 23:08:19 +02001081 tv = ALLOC_ONE(typval_T);
Bram Moolenaar4770d092006-01-12 23:22:24 +00001082 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL)
Bram Moolenaard23a8232018-02-10 18:45:26 +01001083 VIM_CLEAR(tv);
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00001084
1085 return tv;
1086}
1087
1088
Bram Moolenaar071d4272004-06-13 20:20:40 +00001089/*
Bram Moolenaarb544f3c2017-02-23 19:03:28 +01001090 * Call some Vim script function and return the result in "*rettv".
Bram Moolenaarffa96842018-06-12 22:05:14 +02001091 * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc]
1092 * should have type VAR_UNKNOWN.
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001093 * Returns OK or FAIL.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001094 */
Bram Moolenaar82139082011-09-14 16:52:09 +02001095 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001096call_vim_function(
1097 char_u *func,
1098 int argc,
Bram Moolenaarffa96842018-06-12 22:05:14 +02001099 typval_T *argv,
Bram Moolenaarded27a12018-08-01 19:06:03 +02001100 typval_T *rettv)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001101{
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001102 int ret;
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02001103 funcexe_T funcexe;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001104
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001105 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
Bram Moolenaarc6538bc2019-08-03 18:17:11 +02001106 vim_memset(&funcexe, 0, sizeof(funcexe));
1107 funcexe.firstline = curwin->w_cursor.lnum;
1108 funcexe.lastline = curwin->w_cursor.lnum;
1109 funcexe.evaluate = TRUE;
1110 ret = call_func(func, -1, rettv, argc, argv, &funcexe);
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001111 if (ret == FAIL)
1112 clear_tv(rettv);
1113
1114 return ret;
1115}
1116
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +01001117/*
Bram Moolenaarb544f3c2017-02-23 19:03:28 +01001118 * Call Vim script function "func" and return the result as a number.
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +01001119 * Returns -1 when calling the function fails.
Bram Moolenaarffa96842018-06-12 22:05:14 +02001120 * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
1121 * have type VAR_UNKNOWN.
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +01001122 */
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001123 varnumber_T
Bram Moolenaar7454a062016-01-30 15:14:10 +01001124call_func_retnr(
1125 char_u *func,
1126 int argc,
Bram Moolenaarded27a12018-08-01 19:06:03 +02001127 typval_T *argv)
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +01001128{
1129 typval_T rettv;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001130 varnumber_T retval;
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +01001131
Bram Moolenaarded27a12018-08-01 19:06:03 +02001132 if (call_vim_function(func, argc, argv, &rettv) == FAIL)
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +01001133 return -1;
1134
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001135 retval = tv_get_number_chk(&rettv, NULL);
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +01001136 clear_tv(&rettv);
1137 return retval;
1138}
1139
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001140/*
Bram Moolenaarb544f3c2017-02-23 19:03:28 +01001141 * Call Vim script function "func" and return the result as a string.
Bram Moolenaar25ceb222005-07-30 22:45:36 +00001142 * Returns NULL when calling the function fails.
Bram Moolenaarffa96842018-06-12 22:05:14 +02001143 * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
1144 * have type VAR_UNKNOWN.
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001145 */
1146 void *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001147call_func_retstr(
1148 char_u *func,
1149 int argc,
Bram Moolenaarded27a12018-08-01 19:06:03 +02001150 typval_T *argv)
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001151{
1152 typval_T rettv;
Bram Moolenaar25ceb222005-07-30 22:45:36 +00001153 char_u *retval;
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001154
Bram Moolenaarded27a12018-08-01 19:06:03 +02001155 if (call_vim_function(func, argc, argv, &rettv) == FAIL)
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001156 return NULL;
1157
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001158 retval = vim_strsave(tv_get_string(&rettv));
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001159 clear_tv(&rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001160 return retval;
1161}
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001162
Bram Moolenaar25ceb222005-07-30 22:45:36 +00001163/*
Bram Moolenaarb544f3c2017-02-23 19:03:28 +01001164 * Call Vim script function "func" and return the result as a List.
Bram Moolenaarffa96842018-06-12 22:05:14 +02001165 * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
1166 * have type VAR_UNKNOWN.
Bram Moolenaar9bf749b2008-07-27 13:57:29 +00001167 * Returns NULL when there is something wrong.
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001168 */
1169 void *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001170call_func_retlist(
1171 char_u *func,
1172 int argc,
Bram Moolenaarded27a12018-08-01 19:06:03 +02001173 typval_T *argv)
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001174{
1175 typval_T rettv;
1176
Bram Moolenaarded27a12018-08-01 19:06:03 +02001177 if (call_vim_function(func, argc, argv, &rettv) == FAIL)
Bram Moolenaard8e9bb22005-07-09 21:14:46 +00001178 return NULL;
1179
1180 if (rettv.v_type != VAR_LIST)
1181 {
1182 clear_tv(&rettv);
1183 return NULL;
1184 }
1185
1186 return rettv.vval.v_list;
1187}
Bram Moolenaar071d4272004-06-13 20:20:40 +00001188
Bram Moolenaar05159a02005-02-26 23:04:13 +00001189
Bram Moolenaar071d4272004-06-13 20:20:40 +00001190#ifdef FEAT_FOLDING
1191/*
1192 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding
1193 * it in "*cp". Doesn't give error messages.
1194 */
1195 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001196eval_foldexpr(char_u *arg, int *cp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001197{
Bram Moolenaar33570922005-01-25 22:26:29 +00001198 typval_T tv;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001199 varnumber_T retval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001200 char_u *s;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00001201 int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
1202 OPT_LOCAL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001203
1204 ++emsg_off;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001205 if (use_sandbox)
1206 ++sandbox;
1207 ++textlock;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001208 *cp = NUL;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001209 if (eval0(arg, &tv, NULL, TRUE) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001210 retval = 0;
1211 else
1212 {
1213 /* If the result is a number, just return the number. */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001214 if (tv.v_type == VAR_NUMBER)
1215 retval = tv.vval.v_number;
Bram Moolenaar758711c2005-02-02 23:11:38 +00001216 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001217 retval = 0;
1218 else
1219 {
1220 /* If the result is a string, check if there is a non-digit before
1221 * the number. */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001222 s = tv.vval.v_string;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001223 if (!VIM_ISDIGIT(*s) && *s != '-')
1224 *cp = *s++;
1225 retval = atol((char *)s);
1226 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001227 clear_tv(&tv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001228 }
1229 --emsg_off;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001230 if (use_sandbox)
1231 --sandbox;
1232 --textlock;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001233
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001234 return (int)retval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001235}
1236#endif
1237
Bram Moolenaar071d4272004-06-13 20:20:40 +00001238/*
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001239 * Get an lval: variable, Dict item or List item that can be assigned a value
1240 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
1241 * "name.key", "name.key[expr]" etc.
1242 * Indexing only works if "name" is an existing List or Dictionary.
1243 * "name" points to the start of the name.
1244 * If "rettv" is not NULL it points to the value to be assigned.
1245 * "unlet" is TRUE for ":unlet": slightly different behavior when something is
1246 * wrong; must end in space or cmd separator.
1247 *
Bram Moolenaar6d977d62014-01-14 15:24:39 +01001248 * flags:
1249 * GLV_QUIET: do not give error messages
Bram Moolenaar3a257732017-02-21 20:47:13 +01001250 * GLV_READ_ONLY: will not change the variable
Bram Moolenaar6d977d62014-01-14 15:24:39 +01001251 * GLV_NO_AUTOLOAD: do not use script autoloading
1252 *
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001253 * Returns a pointer to just after the name, including indexes.
Bram Moolenaara7043832005-01-21 11:56:39 +00001254 * When an evaluation error occurs "lp->ll_name" is NULL;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001255 * Returns NULL for a parsing error. Still need to free items in "lp"!
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001256 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001257 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01001258get_lval(
1259 char_u *name,
1260 typval_T *rettv,
1261 lval_T *lp,
1262 int unlet,
1263 int skip,
1264 int flags, /* GLV_ values */
1265 int fne_flags) /* flags for find_name_end() */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001266{
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001267 char_u *p;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001268 char_u *expr_start, *expr_end;
1269 int cc;
Bram Moolenaar33570922005-01-25 22:26:29 +00001270 dictitem_T *v;
1271 typval_T var1;
1272 typval_T var2;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001273 int empty1 = FALSE;
Bram Moolenaar33570922005-01-25 22:26:29 +00001274 listitem_T *ni;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001275 char_u *key = NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001276 int len;
Bram Moolenaar33570922005-01-25 22:26:29 +00001277 hashtab_T *ht;
Bram Moolenaar6d977d62014-01-14 15:24:39 +01001278 int quiet = flags & GLV_QUIET;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001279
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001280 /* Clear everything in "lp". */
Bram Moolenaar33570922005-01-25 22:26:29 +00001281 vim_memset(lp, 0, sizeof(lval_T));
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001282
1283 if (skip)
1284 {
1285 /* When skipping just find the end of the name. */
1286 lp->ll_name = name;
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00001287 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001288 }
1289
1290 /* Find the end of the name. */
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00001291 p = find_name_end(name, &expr_start, &expr_end, fne_flags);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001292 if (expr_start != NULL)
1293 {
1294 /* Don't expand the name when we already know there is an error. */
Bram Moolenaar1c465442017-03-12 20:10:05 +01001295 if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p)
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001296 && *p != '[' && *p != '.')
1297 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001298 emsg(_(e_trailing));
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001299 return NULL;
1300 }
1301
1302 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
1303 if (lp->ll_exp_name == NULL)
1304 {
1305 /* Report an invalid expression in braces, unless the
1306 * expression evaluation has been cancelled due to an
1307 * aborting error, an interrupt, or an exception. */
1308 if (!aborting() && !quiet)
1309 {
Bram Moolenaarce5e58e2005-01-19 22:24:34 +00001310 emsg_severe = TRUE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001311 semsg(_(e_invarg2), name);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001312 return NULL;
1313 }
1314 }
1315 lp->ll_name = lp->ll_exp_name;
1316 }
1317 else
1318 lp->ll_name = name;
1319
1320 /* Without [idx] or .key we are done. */
1321 if ((*p != '[' && *p != '.') || lp->ll_name == NULL)
1322 return p;
1323
1324 cc = *p;
1325 *p = NUL;
Bram Moolenaar6e65d592017-12-07 22:11:27 +01001326 /* Only pass &ht when we would write to the variable, it prevents autoload
1327 * as well. */
1328 v = find_var(lp->ll_name, (flags & GLV_READ_ONLY) ? NULL : &ht,
1329 flags & GLV_NO_AUTOLOAD);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001330 if (v == NULL && !quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001331 semsg(_(e_undefvar), lp->ll_name);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001332 *p = cc;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001333 if (v == NULL)
1334 return NULL;
1335
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001336 /*
1337 * Loop until no more [idx] or .key is following.
1338 */
Bram Moolenaar33570922005-01-25 22:26:29 +00001339 lp->ll_tv = &v->di_tv;
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001340 var1.v_type = VAR_UNKNOWN;
1341 var2.v_type = VAR_UNKNOWN;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001342 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001343 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001344 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
1345 && !(lp->ll_tv->v_type == VAR_DICT
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001346 && lp->ll_tv->vval.v_dict != NULL)
1347 && !(lp->ll_tv->v_type == VAR_BLOB
1348 && lp->ll_tv->vval.v_blob != NULL))
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001349 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001350 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001351 emsg(_("E689: Can only index a List, Dictionary or Blob"));
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001352 return NULL;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001353 }
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001354 if (lp->ll_range)
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001355 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001356 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001357 emsg(_("E708: [:] must come last"));
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001358 return NULL;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001359 }
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001360
Bram Moolenaar8c711452005-01-14 21:53:12 +00001361 len = -1;
1362 if (*p == '.')
1363 {
1364 key = p + 1;
1365 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
1366 ;
1367 if (len == 0)
1368 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001369 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001370 emsg(_(e_emptykey));
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001371 return NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001372 }
1373 p = key + len;
1374 }
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001375 else
1376 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00001377 /* Get the index [expr] or the first index [expr: ]. */
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001378 p = skipwhite(p + 1);
Bram Moolenaar8c711452005-01-14 21:53:12 +00001379 if (*p == ':')
1380 empty1 = TRUE;
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001381 else
1382 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00001383 empty1 = FALSE;
1384 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001385 return NULL;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001386 if (tv_get_string_chk(&var1) == NULL)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00001387 {
1388 /* not a number or string */
1389 clear_tv(&var1);
1390 return NULL;
1391 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00001392 }
1393
1394 /* Optionally get the second index [ :expr]. */
1395 if (*p == ':')
1396 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001397 if (lp->ll_tv->v_type == VAR_DICT)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001398 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001399 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001400 emsg(_(e_dictrange));
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001401 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001402 return NULL;
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001403 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001404 if (rettv != NULL
1405 && !(rettv->v_type == VAR_LIST
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001406 && rettv->vval.v_list != NULL)
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001407 && !(rettv->v_type == VAR_BLOB
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001408 && rettv->vval.v_blob != NULL))
Bram Moolenaar8c711452005-01-14 21:53:12 +00001409 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001410 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001411 emsg(_("E709: [:] requires a List or Blob value"));
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001412 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001413 return NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001414 }
1415 p = skipwhite(p + 1);
1416 if (*p == ']')
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001417 lp->ll_empty2 = TRUE;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001418 else
1419 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001420 lp->ll_empty2 = FALSE;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001421 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */
1422 {
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001423 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001424 return NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001425 }
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001426 if (tv_get_string_chk(&var2) == NULL)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00001427 {
1428 /* not a number or string */
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001429 clear_tv(&var1);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00001430 clear_tv(&var2);
1431 return NULL;
1432 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00001433 }
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001434 lp->ll_range = TRUE;
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001435 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00001436 else
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001437 lp->ll_range = FALSE;
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001438
Bram Moolenaar8c711452005-01-14 21:53:12 +00001439 if (*p != ']')
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001440 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001441 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001442 emsg(_(e_missbrac));
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001443 clear_tv(&var1);
1444 clear_tv(&var2);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001445 return NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001446 }
1447
1448 /* Skip to past ']'. */
1449 ++p;
1450 }
1451
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001452 if (lp->ll_tv->v_type == VAR_DICT)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001453 {
1454 if (len == -1)
1455 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001456 /* "[key]": get key from "var1" */
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001457 key = tv_get_string_chk(&var1); /* is number or string */
Bram Moolenaar0921ecf2016-04-03 22:44:36 +02001458 if (key == NULL)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001459 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00001460 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001461 return NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001462 }
1463 }
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001464 lp->ll_list = NULL;
1465 lp->ll_dict = lp->ll_tv->vval.v_dict;
Bram Moolenaarce5e58e2005-01-19 22:24:34 +00001466 lp->ll_di = dict_find(lp->ll_dict, key, len);
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001467
Bram Moolenaarbdb62052012-07-16 17:31:53 +02001468 /* When assigning to a scope dictionary check that a function and
1469 * variable name is valid (only variable name unless it is l: or
1470 * g: dictionary). Disallow overwriting a builtin function. */
1471 if (rettv != NULL && lp->ll_dict->dv_scope != 0)
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001472 {
Bram Moolenaarbdb62052012-07-16 17:31:53 +02001473 int prevval;
1474 int wrong;
1475
1476 if (len != -1)
1477 {
1478 prevval = key[len];
1479 key[len] = NUL;
1480 }
Bram Moolenaar4380d1e2013-06-09 20:51:00 +02001481 else
1482 prevval = 0; /* avoid compiler warning */
Bram Moolenaarbdb62052012-07-16 17:31:53 +02001483 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
1484 && rettv->v_type == VAR_FUNC
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001485 && var_check_func_name(key, lp->ll_di == NULL))
Bram Moolenaarbdb62052012-07-16 17:31:53 +02001486 || !valid_varname(key);
1487 if (len != -1)
1488 key[len] = prevval;
1489 if (wrong)
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001490 return NULL;
1491 }
1492
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001493 if (lp->ll_di == NULL)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001494 {
Bram Moolenaar31b81602019-02-10 22:14:27 +01001495 // Can't add "v:" or "a:" variable.
1496 if (lp->ll_dict == &vimvardict
1497 || &lp->ll_dict->dv_hashtab == get_funccal_args_ht())
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001498 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001499 semsg(_(e_illvar), name);
Bram Moolenaarab89d7a2019-03-17 14:43:31 +01001500 clear_tv(&var1);
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001501 return NULL;
1502 }
1503
Bram Moolenaar31b81602019-02-10 22:14:27 +01001504 // Key does not exist in dict: may need to add it.
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001505 if (*p == '[' || *p == '.' || unlet)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001506 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001507 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001508 semsg(_(e_dictkey), key);
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001509 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001510 return NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001511 }
1512 if (len == -1)
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001513 lp->ll_newkey = vim_strsave(key);
Bram Moolenaar8c711452005-01-14 21:53:12 +00001514 else
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001515 lp->ll_newkey = vim_strnsave(key, len);
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001516 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001517 if (lp->ll_newkey == NULL)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001518 p = NULL;
1519 break;
1520 }
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001521 /* existing variable, need to check if it can be changed */
Bram Moolenaar3a257732017-02-21 20:47:13 +01001522 else if ((flags & GLV_READ_ONLY) == 0
1523 && var_check_ro(lp->ll_di->di_flags, name, FALSE))
Bram Moolenaar49439c42017-02-20 23:07:05 +01001524 {
1525 clear_tv(&var1);
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001526 return NULL;
Bram Moolenaar49439c42017-02-20 23:07:05 +01001527 }
Bram Moolenaar4228bec2011-03-27 16:03:15 +02001528
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001529 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001530 lp->ll_tv = &lp->ll_di->di_tv;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001531 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001532 else if (lp->ll_tv->v_type == VAR_BLOB)
1533 {
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001534 long bloblen = blob_len(lp->ll_tv->vval.v_blob);
1535
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001536 /*
1537 * Get the number and item for the only or first index of the List.
1538 */
1539 if (empty1)
1540 lp->ll_n1 = 0;
1541 else
1542 // is number or string
1543 lp->ll_n1 = (long)tv_get_number(&var1);
1544 clear_tv(&var1);
1545
1546 if (lp->ll_n1 < 0
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001547 || lp->ll_n1 > bloblen
1548 || (lp->ll_range && lp->ll_n1 == bloblen))
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001549 {
1550 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001551 semsg(_(e_blobidx), lp->ll_n1);
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001552 clear_tv(&var2);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001553 return NULL;
1554 }
1555 if (lp->ll_range && !lp->ll_empty2)
1556 {
1557 lp->ll_n2 = (long)tv_get_number(&var2);
1558 clear_tv(&var2);
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001559 if (lp->ll_n2 < 0
1560 || lp->ll_n2 >= bloblen
1561 || lp->ll_n2 < lp->ll_n1)
1562 {
1563 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001564 semsg(_(e_blobidx), lp->ll_n2);
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001565 return NULL;
1566 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001567 }
1568 lp->ll_blob = lp->ll_tv->vval.v_blob;
1569 lp->ll_tv = NULL;
Bram Moolenaar61be3762019-03-19 23:04:17 +01001570 break;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001571 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00001572 else
1573 {
1574 /*
1575 * Get the number and item for the only or first index of the List.
1576 */
1577 if (empty1)
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001578 lp->ll_n1 = 0;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001579 else
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001580 /* is number or string */
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001581 lp->ll_n1 = (long)tv_get_number(&var1);
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001582 clear_tv(&var1);
1583
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001584 lp->ll_dict = NULL;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001585 lp->ll_list = lp->ll_tv->vval.v_list;
1586 lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
1587 if (lp->ll_li == NULL)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001588 {
Bram Moolenaarf9393ef2006-04-24 19:47:27 +00001589 if (lp->ll_n1 < 0)
1590 {
1591 lp->ll_n1 = 0;
1592 lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
1593 }
1594 }
1595 if (lp->ll_li == NULL)
1596 {
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001597 clear_tv(&var2);
Bram Moolenaare9623882011-04-21 14:27:28 +02001598 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001599 semsg(_(e_listidx), lp->ll_n1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001600 return NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00001601 }
1602
1603 /*
1604 * May need to find the item or absolute index for the second
1605 * index of a range.
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001606 * When no index given: "lp->ll_empty2" is TRUE.
1607 * Otherwise "lp->ll_n2" is set to the second index.
Bram Moolenaar8c711452005-01-14 21:53:12 +00001608 */
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001609 if (lp->ll_range && !lp->ll_empty2)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001610 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001611 lp->ll_n2 = (long)tv_get_number(&var2);
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001612 /* is number or string */
Bram Moolenaar8c711452005-01-14 21:53:12 +00001613 clear_tv(&var2);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001614 if (lp->ll_n2 < 0)
Bram Moolenaar8c711452005-01-14 21:53:12 +00001615 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001616 ni = list_find(lp->ll_list, lp->ll_n2);
Bram Moolenaar8c711452005-01-14 21:53:12 +00001617 if (ni == NULL)
Bram Moolenaare9623882011-04-21 14:27:28 +02001618 {
1619 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001620 semsg(_(e_listidx), lp->ll_n2);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001621 return NULL;
Bram Moolenaare9623882011-04-21 14:27:28 +02001622 }
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001623 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni);
Bram Moolenaar8c711452005-01-14 21:53:12 +00001624 }
1625
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001626 /* Check that lp->ll_n2 isn't before lp->ll_n1. */
1627 if (lp->ll_n1 < 0)
1628 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
1629 if (lp->ll_n2 < lp->ll_n1)
Bram Moolenaare9623882011-04-21 14:27:28 +02001630 {
1631 if (!quiet)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001632 semsg(_(e_listidx), lp->ll_n2);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001633 return NULL;
Bram Moolenaare9623882011-04-21 14:27:28 +02001634 }
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001635 }
1636
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001637 lp->ll_tv = &lp->ll_li->li_tv;
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001638 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001639 }
1640
Bram Moolenaarf06e5a52017-02-23 14:25:17 +01001641 clear_tv(&var1);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001642 return p;
1643}
1644
1645/*
Bram Moolenaar33570922005-01-25 22:26:29 +00001646 * Clear lval "lp" that was filled by get_lval().
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001647 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02001648 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01001649clear_lval(lval_T *lp)
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001650{
1651 vim_free(lp->ll_exp_name);
1652 vim_free(lp->ll_newkey);
1653}
1654
1655/*
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00001656 * Set a variable that was parsed by get_lval() to "rettv".
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001657 * "endp" points to just after the parsed name.
Bram Moolenaarff697e62019-02-12 22:28:33 +01001658 * "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=",
1659 * "%" for "%=", "." for ".=" or "=" for "=".
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001660 */
Bram Moolenaar0522ba02019-08-27 22:48:30 +02001661 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01001662set_var_lval(
1663 lval_T *lp,
1664 char_u *endp,
1665 typval_T *rettv,
1666 int copy,
Bram Moolenaar9937a052019-06-15 15:45:06 +02001667 int is_const, // Disallow to modify existing variable for :const
Bram Moolenaar7454a062016-01-30 15:14:10 +01001668 char_u *op)
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001669{
1670 int cc;
Bram Moolenaar33570922005-01-25 22:26:29 +00001671 listitem_T *ri;
1672 dictitem_T *di;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001673
1674 if (lp->ll_tv == NULL)
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001675 {
Bram Moolenaar79518e22017-02-17 16:31:35 +01001676 cc = *endp;
1677 *endp = NUL;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001678 if (lp->ll_blob != NULL)
1679 {
1680 int error = FALSE, val;
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001681
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001682 if (op != NULL && *op != '=')
1683 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001684 semsg(_(e_letwrong), op);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001685 return;
1686 }
1687
1688 if (lp->ll_range && rettv->v_type == VAR_BLOB)
1689 {
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001690 int il, ir;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001691
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001692 if (lp->ll_empty2)
1693 lp->ll_n2 = blob_len(lp->ll_blob) - 1;
1694
1695 if (lp->ll_n2 - lp->ll_n1 + 1 != blob_len(rettv->vval.v_blob))
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001696 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001697 emsg(_("E972: Blob value does not have the right number of bytes"));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001698 return;
1699 }
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001700 if (lp->ll_empty2)
1701 lp->ll_n2 = blob_len(lp->ll_blob);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001702
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001703 ir = 0;
1704 for (il = lp->ll_n1; il <= lp->ll_n2; il++)
1705 blob_set(lp->ll_blob, il,
1706 blob_get(rettv->vval.v_blob, ir++));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001707 }
1708 else
1709 {
1710 val = (int)tv_get_number_chk(rettv, &error);
1711 if (!error)
1712 {
1713 garray_T *gap = &lp->ll_blob->bv_ga;
1714
1715 // Allow for appending a byte. Setting a byte beyond
1716 // the end is an error otherwise.
1717 if (lp->ll_n1 < gap->ga_len
1718 || (lp->ll_n1 == gap->ga_len
1719 && ga_grow(&lp->ll_blob->bv_ga, 1) == OK))
1720 {
1721 blob_set(lp->ll_blob, lp->ll_n1, val);
1722 if (lp->ll_n1 == gap->ga_len)
1723 ++gap->ga_len;
1724 }
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001725 // error for invalid range was already given in get_lval()
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001726 }
1727 }
1728 }
1729 else if (op != NULL && *op != '=')
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001730 {
Bram Moolenaar79518e22017-02-17 16:31:35 +01001731 typval_T tv;
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001732
Bram Moolenaar9937a052019-06-15 15:45:06 +02001733 if (is_const)
1734 {
1735 emsg(_(e_cannot_mod));
1736 *endp = cc;
1737 return;
1738 }
1739
Bram Moolenaarff697e62019-02-12 22:28:33 +01001740 // handle +=, -=, *=, /=, %= and .=
Bram Moolenaar79518e22017-02-17 16:31:35 +01001741 di = NULL;
1742 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
1743 &tv, &di, TRUE, FALSE) == OK)
1744 {
1745 if ((di == NULL
Bram Moolenaar05c00c02019-02-11 22:00:11 +01001746 || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
1747 && !tv_check_lock(&di->di_tv, lp->ll_name, FALSE)))
Bram Moolenaar79518e22017-02-17 16:31:35 +01001748 && tv_op(&tv, rettv, op) == OK)
1749 set_var(lp->ll_name, &tv, FALSE);
1750 clear_tv(&tv);
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001751 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001752 }
Bram Moolenaar79518e22017-02-17 16:31:35 +01001753 else
Bram Moolenaar9937a052019-06-15 15:45:06 +02001754 set_var_const(lp->ll_name, rettv, copy, is_const);
Bram Moolenaar79518e22017-02-17 16:31:35 +01001755 *endp = cc;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001756 }
Bram Moolenaar05c00c02019-02-11 22:00:11 +01001757 else if (var_check_lock(lp->ll_newkey == NULL
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00001758 ? lp->ll_tv->v_lock
Bram Moolenaar77354e72015-04-21 16:49:05 +02001759 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE))
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00001760 ;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001761 else if (lp->ll_range)
1762 {
Bram Moolenaarf2d912e2014-08-29 09:46:10 +02001763 listitem_T *ll_li = lp->ll_li;
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01001764 int ll_n1 = lp->ll_n1;
Bram Moolenaarf2d912e2014-08-29 09:46:10 +02001765
Bram Moolenaar9937a052019-06-15 15:45:06 +02001766 if (is_const)
1767 {
1768 emsg(_("E996: Cannot lock a range"));
1769 return;
1770 }
1771
Bram Moolenaarf2d912e2014-08-29 09:46:10 +02001772 /*
1773 * Check whether any of the list items is locked
1774 */
Bram Moolenaarb2a851f2014-12-07 00:18:33 +01001775 for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; )
Bram Moolenaarf2d912e2014-08-29 09:46:10 +02001776 {
Bram Moolenaar05c00c02019-02-11 22:00:11 +01001777 if (var_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE))
Bram Moolenaarf2d912e2014-08-29 09:46:10 +02001778 return;
1779 ri = ri->li_next;
1780 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1))
1781 break;
1782 ll_li = ll_li->li_next;
1783 ++ll_n1;
1784 }
1785
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001786 /*
1787 * Assign the List values to the list items.
1788 */
1789 for (ri = rettv->vval.v_list->lv_first; ri != NULL; )
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001790 {
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001791 if (op != NULL && *op != '=')
1792 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op);
1793 else
1794 {
1795 clear_tv(&lp->ll_li->li_tv);
1796 copy_tv(&ri->li_tv, &lp->ll_li->li_tv);
1797 }
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001798 ri = ri->li_next;
1799 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1))
1800 break;
1801 if (lp->ll_li->li_next == NULL)
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001802 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001803 /* Need to add an empty item. */
Bram Moolenaar4463f292005-09-25 22:20:24 +00001804 if (list_append_number(lp->ll_list, 0) == FAIL)
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001805 {
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001806 ri = NULL;
1807 break;
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001808 }
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001809 }
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001810 lp->ll_li = lp->ll_li->li_next;
1811 ++lp->ll_n1;
1812 }
1813 if (ri != NULL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001814 emsg(_("E710: List value has more items than target"));
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001815 else if (lp->ll_empty2
1816 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL)
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001817 : lp->ll_n1 != lp->ll_n2)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001818 emsg(_("E711: List value has not enough items"));
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001819 }
1820 else
1821 {
1822 /*
1823 * Assign to a List or Dictionary item.
1824 */
Bram Moolenaar9937a052019-06-15 15:45:06 +02001825 if (is_const)
1826 {
1827 emsg(_("E996: Cannot lock a list or dict"));
1828 return;
1829 }
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001830 if (lp->ll_newkey != NULL)
1831 {
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001832 if (op != NULL && *op != '=')
1833 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001834 semsg(_(e_letwrong), op);
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001835 return;
1836 }
1837
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001838 /* Need to add an item to the Dictionary. */
Bram Moolenaarce5e58e2005-01-19 22:24:34 +00001839 di = dictitem_alloc(lp->ll_newkey);
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001840 if (di == NULL)
1841 return;
Bram Moolenaarce5e58e2005-01-19 22:24:34 +00001842 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL)
1843 {
1844 vim_free(di);
1845 return;
1846 }
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001847 lp->ll_tv = &di->di_tv;
Bram Moolenaar6cc16192005-01-08 21:49:45 +00001848 }
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001849 else if (op != NULL && *op != '=')
1850 {
1851 tv_op(lp->ll_tv, rettv, op);
1852 return;
1853 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001854 else
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001855 clear_tv(lp->ll_tv);
Bram Moolenaar8c711452005-01-14 21:53:12 +00001856
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001857 /*
1858 * Assign the value to the variable or list item.
1859 */
1860 if (copy)
1861 copy_tv(rettv, lp->ll_tv);
1862 else
1863 {
1864 *lp->ll_tv = *rettv;
Bram Moolenaar758711c2005-02-02 23:11:38 +00001865 lp->ll_tv->v_lock = 0;
Bram Moolenaar7480b5c2005-01-16 22:07:38 +00001866 init_tv(rettv);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001867 }
1868 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00001869}
1870
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00001871/*
Bram Moolenaarff697e62019-02-12 22:28:33 +01001872 * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2"
1873 * and "tv1 .= tv2"
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001874 * Returns OK or FAIL.
1875 */
1876 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001877tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001878{
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001879 varnumber_T n;
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001880 char_u numbuf[NUMBUFLEN];
1881 char_u *s;
1882
Bram Moolenaar520e1e42016-01-23 19:46:28 +01001883 /* Can't do anything with a Funcref, Dict, v:true on the right. */
1884 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
1885 && tv2->v_type != VAR_SPECIAL)
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001886 {
1887 switch (tv1->v_type)
1888 {
Bram Moolenaar835dc632016-02-07 14:27:38 +01001889 case VAR_UNKNOWN:
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001890 case VAR_DICT:
1891 case VAR_FUNC:
Bram Moolenaar1735bc92016-03-14 23:05:14 +01001892 case VAR_PARTIAL:
Bram Moolenaar520e1e42016-01-23 19:46:28 +01001893 case VAR_SPECIAL:
Bram Moolenaar835dc632016-02-07 14:27:38 +01001894 case VAR_JOB:
Bram Moolenaar77073442016-02-13 23:23:53 +01001895 case VAR_CHANNEL:
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001896 break;
1897
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01001898 case VAR_BLOB:
1899 if (*op != '+' || tv2->v_type != VAR_BLOB)
1900 break;
1901 // BLOB += BLOB
1902 if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL)
1903 {
1904 blob_T *b1 = tv1->vval.v_blob;
1905 blob_T *b2 = tv2->vval.v_blob;
1906 int i, len = blob_len(b2);
1907 for (i = 0; i < len; i++)
1908 ga_append(&b1->bv_ga, blob_get(b2, i));
1909 }
1910 return OK;
1911
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001912 case VAR_LIST:
1913 if (*op != '+' || tv2->v_type != VAR_LIST)
1914 break;
Bram Moolenaarff697e62019-02-12 22:28:33 +01001915 // List += List
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001916 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL)
1917 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
1918 return OK;
1919
1920 case VAR_NUMBER:
1921 case VAR_STRING:
1922 if (tv2->v_type == VAR_LIST)
1923 break;
Bram Moolenaarff697e62019-02-12 22:28:33 +01001924 if (vim_strchr((char_u *)"+-*/%", *op) != NULL)
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001925 {
Bram Moolenaarff697e62019-02-12 22:28:33 +01001926 // nr += nr , nr -= nr , nr *=nr , nr /= nr , nr %= nr
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001927 n = tv_get_number(tv1);
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001928#ifdef FEAT_FLOAT
1929 if (tv2->v_type == VAR_FLOAT)
1930 {
1931 float_T f = n;
1932
Bram Moolenaarff697e62019-02-12 22:28:33 +01001933 if (*op == '%')
1934 break;
1935 switch (*op)
1936 {
1937 case '+': f += tv2->vval.v_float; break;
1938 case '-': f -= tv2->vval.v_float; break;
1939 case '*': f *= tv2->vval.v_float; break;
1940 case '/': f /= tv2->vval.v_float; break;
1941 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001942 clear_tv(tv1);
1943 tv1->v_type = VAR_FLOAT;
1944 tv1->vval.v_float = f;
1945 }
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001946 else
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001947#endif
1948 {
Bram Moolenaarff697e62019-02-12 22:28:33 +01001949 switch (*op)
1950 {
1951 case '+': n += tv_get_number(tv2); break;
1952 case '-': n -= tv_get_number(tv2); break;
1953 case '*': n *= tv_get_number(tv2); break;
Bram Moolenaare21c1582019-03-02 11:57:09 +01001954 case '/': n = num_divide(n, tv_get_number(tv2)); break;
1955 case '%': n = num_modulus(n, tv_get_number(tv2)); break;
Bram Moolenaarff697e62019-02-12 22:28:33 +01001956 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001957 clear_tv(tv1);
1958 tv1->v_type = VAR_NUMBER;
1959 tv1->vval.v_number = n;
1960 }
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001961 }
1962 else
1963 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001964 if (tv2->v_type == VAR_FLOAT)
1965 break;
1966
Bram Moolenaarff697e62019-02-12 22:28:33 +01001967 // str .= str
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001968 s = tv_get_string(tv1);
1969 s = concat_str(s, tv_get_string_buf(tv2, numbuf));
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00001970 clear_tv(tv1);
1971 tv1->v_type = VAR_STRING;
1972 tv1->vval.v_string = s;
1973 }
1974 return OK;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001975
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001976 case VAR_FLOAT:
Bram Moolenaar5fac4672016-03-02 22:16:32 +01001977#ifdef FEAT_FLOAT
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001978 {
1979 float_T f;
1980
Bram Moolenaarff697e62019-02-12 22:28:33 +01001981 if (*op == '%' || *op == '.'
1982 || (tv2->v_type != VAR_FLOAT
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001983 && tv2->v_type != VAR_NUMBER
1984 && tv2->v_type != VAR_STRING))
1985 break;
1986 if (tv2->v_type == VAR_FLOAT)
1987 f = tv2->vval.v_float;
1988 else
Bram Moolenaard155d7a2018-12-21 16:04:21 +01001989 f = tv_get_number(tv2);
Bram Moolenaarff697e62019-02-12 22:28:33 +01001990 switch (*op)
1991 {
1992 case '+': tv1->vval.v_float += f; break;
1993 case '-': tv1->vval.v_float -= f; break;
1994 case '*': tv1->vval.v_float *= f; break;
1995 case '/': tv1->vval.v_float /= f; break;
1996 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001997 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001998#endif
Bram Moolenaar5fac4672016-03-02 22:16:32 +01001999 return OK;
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00002000 }
2001 }
2002
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002003 semsg(_(e_letwrong), op);
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00002004 return FAIL;
2005}
2006
2007/*
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002008 * Evaluate the expression used in a ":for var in expr" command.
2009 * "arg" points to "var".
2010 * Set "*errp" to TRUE for an error, FALSE otherwise;
2011 * Return a pointer that holds the info. Null when there is an error.
2012 */
2013 void *
Bram Moolenaar7454a062016-01-30 15:14:10 +01002014eval_for_line(
2015 char_u *arg,
2016 int *errp,
2017 char_u **nextcmdp,
2018 int skip)
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002019{
Bram Moolenaar33570922005-01-25 22:26:29 +00002020 forinfo_T *fi;
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002021 char_u *expr;
Bram Moolenaar33570922005-01-25 22:26:29 +00002022 typval_T tv;
2023 list_T *l;
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002024
2025 *errp = TRUE; /* default: there is an error */
2026
Bram Moolenaarc799fe22019-05-28 23:08:19 +02002027 fi = ALLOC_CLEAR_ONE(forinfo_T);
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002028 if (fi == NULL)
2029 return NULL;
2030
2031 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
2032 if (expr == NULL)
2033 return fi;
2034
2035 expr = skipwhite(expr);
Bram Moolenaar1c465442017-03-12 20:10:05 +01002036 if (expr[0] != 'i' || expr[1] != 'n' || !VIM_ISWHITE(expr[2]))
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002037 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002038 emsg(_("E690: Missing \"in\" after :for"));
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002039 return fi;
2040 }
2041
2042 if (skip)
2043 ++emsg_skip;
2044 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK)
2045 {
2046 *errp = FALSE;
2047 if (!skip)
2048 {
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002049 if (tv.v_type == VAR_LIST)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00002050 {
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002051 l = tv.vval.v_list;
2052 if (l == NULL)
2053 {
2054 // a null list is like an empty list: do nothing
2055 clear_tv(&tv);
2056 }
2057 else
2058 {
2059 // No need to increment the refcount, it's already set for
2060 // the list being used in "tv".
2061 fi->fi_list = l;
2062 list_add_watch(l, &fi->fi_lw);
2063 fi->fi_lw.lw_item = l->lv_first;
2064 }
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00002065 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002066 else if (tv.v_type == VAR_BLOB)
Bram Moolenaard8585ed2016-05-01 23:05:53 +02002067 {
Bram Moolenaardd29ea12019-01-23 21:56:21 +01002068 fi->fi_bi = 0;
2069 if (tv.vval.v_blob != NULL)
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002070 {
Bram Moolenaardd29ea12019-01-23 21:56:21 +01002071 typval_T btv;
2072
2073 // Make a copy, so that the iteration still works when the
2074 // blob is changed.
2075 blob_copy(&tv, &btv);
2076 fi->fi_blob = btv.vval.v_blob;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002077 }
Bram Moolenaardd29ea12019-01-23 21:56:21 +01002078 clear_tv(&tv);
Bram Moolenaard8585ed2016-05-01 23:05:53 +02002079 }
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002080 else
2081 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002082 emsg(_(e_listreq));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002083 clear_tv(&tv);
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002084 }
2085 }
2086 }
2087 if (skip)
2088 --emsg_skip;
2089
2090 return fi;
2091}
2092
2093/*
2094 * Use the first item in a ":for" list. Advance to the next.
2095 * Assign the values to the variable (list). "arg" points to the first one.
2096 * Return TRUE when a valid item was found, FALSE when at end of list or
2097 * something wrong.
2098 */
2099 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002100next_for_item(void *fi_void, char_u *arg)
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002101{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002102 forinfo_T *fi = (forinfo_T *)fi_void;
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002103 int result;
Bram Moolenaar33570922005-01-25 22:26:29 +00002104 listitem_T *item;
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002105
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002106 if (fi->fi_blob != NULL)
2107 {
2108 typval_T tv;
2109
2110 if (fi->fi_bi >= blob_len(fi->fi_blob))
2111 return FALSE;
2112 tv.v_type = VAR_NUMBER;
2113 tv.v_lock = VAR_FIXED;
2114 tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi);
2115 ++fi->fi_bi;
Bram Moolenaar9937a052019-06-15 15:45:06 +02002116 return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon,
2117 fi->fi_varcount, FALSE, NULL) == OK;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002118 }
2119
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002120 item = fi->fi_lw.lw_item;
2121 if (item == NULL)
2122 result = FALSE;
2123 else
2124 {
2125 fi->fi_lw.lw_item = item->li_next;
Bram Moolenaar9937a052019-06-15 15:45:06 +02002126 result = (ex_let_vars(arg, &item->li_tv, TRUE, fi->fi_semicolon,
2127 fi->fi_varcount, FALSE, NULL) == OK);
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002128 }
2129 return result;
2130}
2131
2132/*
2133 * Free the structure used to store info used by ":for".
2134 */
2135 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01002136free_for_info(void *fi_void)
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002137{
Bram Moolenaar33570922005-01-25 22:26:29 +00002138 forinfo_T *fi = (forinfo_T *)fi_void;
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002139
Bram Moolenaarab7013c2005-01-09 21:23:56 +00002140 if (fi != NULL && fi->fi_list != NULL)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00002141 {
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002142 list_rem_watch(fi->fi_list, &fi->fi_lw);
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00002143 list_unref(fi->fi_list);
2144 }
Bram Moolenaarecc8bc42019-01-13 16:07:21 +01002145 if (fi != NULL && fi->fi_blob != NULL)
2146 blob_unref(fi->fi_blob);
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002147 vim_free(fi);
2148}
2149
Bram Moolenaar071d4272004-06-13 20:20:40 +00002150 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01002151set_context_for_expression(
2152 expand_T *xp,
2153 char_u *arg,
2154 cmdidx_T cmdidx)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002155{
2156 int got_eq = FALSE;
2157 int c;
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002158 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002159
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002160 if (cmdidx == CMD_let)
2161 {
2162 xp->xp_context = EXPAND_USER_VARS;
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00002163 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL)
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002164 {
2165 /* ":let var1 var2 ...": find last space. */
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00002166 for (p = arg + STRLEN(arg); p >= arg; )
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002167 {
2168 xp->xp_pattern = p;
Bram Moolenaar91acfff2017-03-12 19:22:36 +01002169 MB_PTR_BACK(arg, p);
Bram Moolenaar1c465442017-03-12 20:10:05 +01002170 if (VIM_ISWHITE(*p))
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002171 break;
2172 }
2173 return;
2174 }
2175 }
2176 else
2177 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
2178 : EXPAND_EXPRESSION;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002179 while ((xp->xp_pattern = vim_strpbrk(arg,
2180 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
2181 {
2182 c = *xp->xp_pattern;
2183 if (c == '&')
2184 {
2185 c = xp->xp_pattern[1];
2186 if (c == '&')
2187 {
2188 ++xp->xp_pattern;
2189 xp->xp_context = cmdidx != CMD_let || got_eq
2190 ? EXPAND_EXPRESSION : EXPAND_NOTHING;
2191 }
2192 else if (c != ' ')
Bram Moolenaar11cbeb12005-03-11 22:51:16 +00002193 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002194 xp->xp_context = EXPAND_SETTINGS;
Bram Moolenaar11cbeb12005-03-11 22:51:16 +00002195 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
2196 xp->xp_pattern += 2;
2197
2198 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002199 }
2200 else if (c == '$')
2201 {
2202 /* environment variable */
2203 xp->xp_context = EXPAND_ENV_VARS;
2204 }
2205 else if (c == '=')
2206 {
2207 got_eq = TRUE;
2208 xp->xp_context = EXPAND_EXPRESSION;
2209 }
Bram Moolenaara32095f2016-03-28 19:27:13 +02002210 else if (c == '#'
2211 && xp->xp_context == EXPAND_EXPRESSION)
2212 {
2213 /* Autoload function/variable contains '#'. */
2214 break;
2215 }
Bram Moolenaar8a349ff2014-11-12 20:09:06 +01002216 else if ((c == '<' || c == '#')
Bram Moolenaar071d4272004-06-13 20:20:40 +00002217 && xp->xp_context == EXPAND_FUNCTIONS
2218 && vim_strchr(xp->xp_pattern, '(') == NULL)
2219 {
Bram Moolenaar8a349ff2014-11-12 20:09:06 +01002220 /* Function name can start with "<SNR>" and contain '#'. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002221 break;
2222 }
2223 else if (cmdidx != CMD_let || got_eq)
2224 {
2225 if (c == '"') /* string */
2226 {
2227 while ((c = *++xp->xp_pattern) != NUL && c != '"')
2228 if (c == '\\' && xp->xp_pattern[1] != NUL)
2229 ++xp->xp_pattern;
2230 xp->xp_context = EXPAND_NOTHING;
2231 }
2232 else if (c == '\'') /* literal string */
2233 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00002234 /* Trick: '' is like stopping and starting a literal string. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002235 while ((c = *++xp->xp_pattern) != NUL && c != '\'')
2236 /* skip */ ;
2237 xp->xp_context = EXPAND_NOTHING;
2238 }
2239 else if (c == '|')
2240 {
2241 if (xp->xp_pattern[1] == '|')
2242 {
2243 ++xp->xp_pattern;
2244 xp->xp_context = EXPAND_EXPRESSION;
2245 }
2246 else
2247 xp->xp_context = EXPAND_COMMANDS;
2248 }
2249 else
2250 xp->xp_context = EXPAND_EXPRESSION;
2251 }
2252 else
Bram Moolenaar3d60ec22005-01-05 22:19:46 +00002253 /* Doesn't look like something valid, expand as an expression
2254 * anyway. */
2255 xp->xp_context = EXPAND_EXPRESSION;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002256 arg = xp->xp_pattern;
2257 if (*arg != NUL)
2258 while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
2259 /* skip */ ;
2260 }
2261 xp->xp_pattern = arg;
2262}
2263
Bram Moolenaar071d4272004-06-13 20:20:40 +00002264#if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
2265/*
2266 * Delete all "menutrans_" variables.
2267 */
2268 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01002269del_menutrans_vars(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002270{
Bram Moolenaar33570922005-01-25 22:26:29 +00002271 hashitem_T *hi;
Bram Moolenaara7043832005-01-21 11:56:39 +00002272 int todo;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002273
Bram Moolenaar33570922005-01-25 22:26:29 +00002274 hash_lock(&globvarht);
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00002275 todo = (int)globvarht.ht_used;
Bram Moolenaar33570922005-01-25 22:26:29 +00002276 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
Bram Moolenaara7043832005-01-21 11:56:39 +00002277 {
2278 if (!HASHITEM_EMPTY(hi))
2279 {
2280 --todo;
Bram Moolenaar33570922005-01-25 22:26:29 +00002281 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
2282 delete_var(&globvarht, hi);
Bram Moolenaara7043832005-01-21 11:56:39 +00002283 }
2284 }
Bram Moolenaar33570922005-01-25 22:26:29 +00002285 hash_unlock(&globvarht);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002286}
2287#endif
2288
Bram Moolenaar071d4272004-06-13 20:20:40 +00002289/*
2290 * Local string buffer for the next two functions to store a variable name
2291 * with its prefix. Allocated in cat_prefix_varname(), freed later in
2292 * get_user_var_name().
2293 */
2294
Bram Moolenaar071d4272004-06-13 20:20:40 +00002295static char_u *varnamebuf = NULL;
2296static int varnamebuflen = 0;
2297
2298/*
2299 * Function to concatenate a prefix and a variable name.
2300 */
2301 static char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01002302cat_prefix_varname(int prefix, char_u *name)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002303{
2304 int len;
2305
2306 len = (int)STRLEN(name) + 3;
2307 if (len > varnamebuflen)
2308 {
2309 vim_free(varnamebuf);
2310 len += 10; /* some additional space */
2311 varnamebuf = alloc(len);
2312 if (varnamebuf == NULL)
2313 {
2314 varnamebuflen = 0;
2315 return NULL;
2316 }
2317 varnamebuflen = len;
2318 }
2319 *varnamebuf = prefix;
2320 varnamebuf[1] = ':';
2321 STRCPY(varnamebuf + 2, name);
2322 return varnamebuf;
2323}
2324
2325/*
2326 * Function given to ExpandGeneric() to obtain the list of user defined
2327 * (global/buffer/window/built-in) variable names.
2328 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002329 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01002330get_user_var_name(expand_T *xp, int idx)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002331{
Bram Moolenaar532c7802005-01-27 14:44:31 +00002332 static long_u gdone;
2333 static long_u bdone;
2334 static long_u wdone;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00002335 static long_u tdone;
Bram Moolenaar532c7802005-01-27 14:44:31 +00002336 static int vidx;
2337 static hashitem_T *hi;
2338 hashtab_T *ht;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002339
2340 if (idx == 0)
Bram Moolenaar910f66f2006-04-05 20:41:53 +00002341 {
Bram Moolenaara7043832005-01-21 11:56:39 +00002342 gdone = bdone = wdone = vidx = 0;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00002343 tdone = 0;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00002344 }
Bram Moolenaar33570922005-01-25 22:26:29 +00002345
2346 /* Global variables */
2347 if (gdone < globvarht.ht_used)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002348 {
Bram Moolenaara7043832005-01-21 11:56:39 +00002349 if (gdone++ == 0)
Bram Moolenaar33570922005-01-25 22:26:29 +00002350 hi = globvarht.ht_array;
Bram Moolenaar532c7802005-01-27 14:44:31 +00002351 else
2352 ++hi;
Bram Moolenaara7043832005-01-21 11:56:39 +00002353 while (HASHITEM_EMPTY(hi))
2354 ++hi;
2355 if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
2356 return cat_prefix_varname('g', hi->hi_key);
2357 return hi->hi_key;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002358 }
Bram Moolenaar33570922005-01-25 22:26:29 +00002359
2360 /* b: variables */
Bram Moolenaar429fa852013-04-15 12:27:36 +02002361 ht = &curbuf->b_vars->dv_hashtab;
Bram Moolenaar33570922005-01-25 22:26:29 +00002362 if (bdone < ht->ht_used)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002363 {
Bram Moolenaara7043832005-01-21 11:56:39 +00002364 if (bdone++ == 0)
Bram Moolenaar33570922005-01-25 22:26:29 +00002365 hi = ht->ht_array;
Bram Moolenaar532c7802005-01-27 14:44:31 +00002366 else
2367 ++hi;
Bram Moolenaara7043832005-01-21 11:56:39 +00002368 while (HASHITEM_EMPTY(hi))
2369 ++hi;
2370 return cat_prefix_varname('b', hi->hi_key);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002371 }
Bram Moolenaar33570922005-01-25 22:26:29 +00002372
2373 /* w: variables */
Bram Moolenaar429fa852013-04-15 12:27:36 +02002374 ht = &curwin->w_vars->dv_hashtab;
Bram Moolenaar33570922005-01-25 22:26:29 +00002375 if (wdone < ht->ht_used)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002376 {
Bram Moolenaarb11bd7e2005-02-07 22:05:52 +00002377 if (wdone++ == 0)
Bram Moolenaar33570922005-01-25 22:26:29 +00002378 hi = ht->ht_array;
Bram Moolenaar532c7802005-01-27 14:44:31 +00002379 else
2380 ++hi;
Bram Moolenaara7043832005-01-21 11:56:39 +00002381 while (HASHITEM_EMPTY(hi))
2382 ++hi;
2383 return cat_prefix_varname('w', hi->hi_key);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002384 }
Bram Moolenaar33570922005-01-25 22:26:29 +00002385
Bram Moolenaar910f66f2006-04-05 20:41:53 +00002386 /* t: variables */
Bram Moolenaar429fa852013-04-15 12:27:36 +02002387 ht = &curtab->tp_vars->dv_hashtab;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00002388 if (tdone < ht->ht_used)
2389 {
2390 if (tdone++ == 0)
2391 hi = ht->ht_array;
2392 else
2393 ++hi;
2394 while (HASHITEM_EMPTY(hi))
2395 ++hi;
2396 return cat_prefix_varname('t', hi->hi_key);
2397 }
Bram Moolenaar910f66f2006-04-05 20:41:53 +00002398
Bram Moolenaar33570922005-01-25 22:26:29 +00002399 /* v: variables */
2400 if (vidx < VV_LEN)
2401 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002402
Bram Moolenaard23a8232018-02-10 18:45:26 +01002403 VIM_CLEAR(varnamebuf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002404 varnamebuflen = 0;
2405 return NULL;
2406}
2407
Bram Moolenaar071d4272004-06-13 20:20:40 +00002408/*
Bram Moolenaarea6553b2016-03-27 15:13:38 +02002409 * Return TRUE if "pat" matches "text".
2410 * Does not use 'cpo' and always uses 'magic'.
2411 */
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02002412 int
Bram Moolenaarea6553b2016-03-27 15:13:38 +02002413pattern_match(char_u *pat, char_u *text, int ic)
2414{
2415 int matches = FALSE;
2416 char_u *save_cpo;
2417 regmatch_T regmatch;
2418
2419 /* avoid 'l' flag in 'cpoptions' */
2420 save_cpo = p_cpo;
2421 p_cpo = (char_u *)"";
2422 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
2423 if (regmatch.regprog != NULL)
2424 {
2425 regmatch.rm_ic = ic;
2426 matches = vim_regexec_nl(&regmatch, text, (colnr_T)0);
2427 vim_regfree(regmatch.regprog);
2428 }
2429 p_cpo = save_cpo;
2430 return matches;
2431}
2432
2433/*
Bram Moolenaar761fdf02019-08-05 23:10:16 +02002434 * Handle a name followed by "(". Both for just "name(arg)" and for
2435 * "expr->name(arg)".
2436 * Returns OK or FAIL.
2437 */
2438 static int
2439eval_func(
2440 char_u **arg, // points to "(", will be advanced
2441 char_u *name,
2442 int name_len,
2443 typval_T *rettv,
2444 int evaluate,
2445 typval_T *basetv) // "expr" for "expr->name(arg)"
2446{
2447 char_u *s = name;
2448 int len = name_len;
2449 partial_T *partial;
2450 int ret = OK;
2451
2452 if (!evaluate)
2453 check_vars(s, len);
2454
2455 /* If "s" is the name of a variable of type VAR_FUNC
2456 * use its contents. */
2457 s = deref_func_name(s, &len, &partial, !evaluate);
2458
2459 /* Need to make a copy, in case evaluating the arguments makes
2460 * the name invalid. */
2461 s = vim_strsave(s);
2462 if (s == NULL)
2463 ret = FAIL;
2464 else
2465 {
2466 funcexe_T funcexe;
2467
2468 // Invoke the function.
2469 vim_memset(&funcexe, 0, sizeof(funcexe));
2470 funcexe.firstline = curwin->w_cursor.lnum;
2471 funcexe.lastline = curwin->w_cursor.lnum;
Bram Moolenaar761fdf02019-08-05 23:10:16 +02002472 funcexe.evaluate = evaluate;
2473 funcexe.partial = partial;
2474 funcexe.basetv = basetv;
2475 ret = get_func_tv(s, len, rettv, arg, &funcexe);
2476 }
2477 vim_free(s);
2478
2479 /* If evaluate is FALSE rettv->v_type was not set in
2480 * get_func_tv, but it's needed in handle_subscript() to parse
2481 * what follows. So set it here. */
2482 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(')
2483 {
2484 rettv->vval.v_string = NULL;
2485 rettv->v_type = VAR_FUNC;
2486 }
2487
2488 /* Stop the expression evaluation when immediately
2489 * aborting on error, or when an interrupt occurred or
2490 * an exception was thrown but not caught. */
2491 if (evaluate && aborting())
2492 {
2493 if (ret == OK)
2494 clear_tv(rettv);
2495 ret = FAIL;
2496 }
2497 return ret;
2498}
2499
2500/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00002501 * The "evaluate" argument: When FALSE, the argument is only parsed but not
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002502 * executed. The function may return OK, but the rettv will be of type
Bram Moolenaar071d4272004-06-13 20:20:40 +00002503 * VAR_UNKNOWN. The function still returns FAIL for a syntax error.
2504 */
2505
2506/*
2507 * Handle zero level expression.
2508 * This calls eval1() and handles error message and nextcmd.
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002509 * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
Bram Moolenaar4463f292005-09-25 22:20:24 +00002510 * Note: "rettv.v_lock" is not set.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002511 * Return OK or FAIL.
2512 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02002513 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002514eval0(
2515 char_u *arg,
2516 typval_T *rettv,
2517 char_u **nextcmd,
2518 int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002519{
2520 int ret;
2521 char_u *p;
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01002522 int did_emsg_before = did_emsg;
2523 int called_emsg_before = called_emsg;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002524
2525 p = skipwhite(arg);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002526 ret = eval1(&p, rettv, evaluate);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002527 if (ret == FAIL || !ends_excmd(*p))
2528 {
2529 if (ret != FAIL)
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002530 clear_tv(rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002531 /*
2532 * Report the invalid expression unless the expression evaluation has
2533 * been cancelled due to an aborting error, an interrupt, or an
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01002534 * exception, or we already gave a more specific error.
2535 * Also check called_emsg for when using assert_fails().
Bram Moolenaar071d4272004-06-13 20:20:40 +00002536 */
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01002537 if (!aborting() && did_emsg == did_emsg_before
2538 && called_emsg == called_emsg_before)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002539 semsg(_(e_invexpr2), arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002540 ret = FAIL;
2541 }
2542 if (nextcmd != NULL)
2543 *nextcmd = check_nextcmd(p);
2544
2545 return ret;
2546}
2547
2548/*
2549 * Handle top level expression:
Bram Moolenaarb67cc162009-02-04 15:27:06 +00002550 * expr2 ? expr1 : expr1
Bram Moolenaar071d4272004-06-13 20:20:40 +00002551 *
2552 * "arg" must point to the first non-white of the expression.
2553 * "arg" is advanced to the next non-white after the recognized expression.
2554 *
Bram Moolenaar4463f292005-09-25 22:20:24 +00002555 * Note: "rettv.v_lock" is not set.
2556 *
Bram Moolenaar071d4272004-06-13 20:20:40 +00002557 * Return OK or FAIL.
2558 */
Bram Moolenaarcd524592016-07-17 14:57:05 +02002559 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002560eval1(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002561{
2562 int result;
Bram Moolenaar33570922005-01-25 22:26:29 +00002563 typval_T var2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002564
2565 /*
2566 * Get the first variable.
2567 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002568 if (eval2(arg, rettv, evaluate) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002569 return FAIL;
2570
2571 if ((*arg)[0] == '?')
2572 {
2573 result = FALSE;
2574 if (evaluate)
2575 {
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002576 int error = FALSE;
2577
Bram Moolenaard155d7a2018-12-21 16:04:21 +01002578 if (tv_get_number_chk(rettv, &error) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002579 result = TRUE;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002580 clear_tv(rettv);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002581 if (error)
2582 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002583 }
2584
2585 /*
2586 * Get the second variable.
2587 */
2588 *arg = skipwhite(*arg + 1);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002589 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002590 return FAIL;
2591
2592 /*
2593 * Check for the ":".
2594 */
2595 if ((*arg)[0] != ':')
2596 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002597 emsg(_("E109: Missing ':' after '?'"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002598 if (evaluate && result)
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002599 clear_tv(rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002600 return FAIL;
2601 }
2602
2603 /*
2604 * Get the third variable.
2605 */
2606 *arg = skipwhite(*arg + 1);
2607 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */
2608 {
2609 if (evaluate && result)
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002610 clear_tv(rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002611 return FAIL;
2612 }
2613 if (evaluate && !result)
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002614 *rettv = var2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002615 }
2616
2617 return OK;
2618}
2619
2620/*
2621 * Handle first level expression:
2622 * expr2 || expr2 || expr2 logical OR
2623 *
2624 * "arg" must point to the first non-white of the expression.
2625 * "arg" is advanced to the next non-white after the recognized expression.
2626 *
2627 * Return OK or FAIL.
2628 */
2629 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002630eval2(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002631{
Bram Moolenaar33570922005-01-25 22:26:29 +00002632 typval_T var2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002633 long result;
2634 int first;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002635 int error = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002636
2637 /*
2638 * Get the first variable.
2639 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002640 if (eval3(arg, rettv, evaluate) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002641 return FAIL;
2642
2643 /*
2644 * Repeat until there is no following "||".
2645 */
2646 first = TRUE;
2647 result = FALSE;
2648 while ((*arg)[0] == '|' && (*arg)[1] == '|')
2649 {
2650 if (evaluate && first)
2651 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01002652 if (tv_get_number_chk(rettv, &error) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002653 result = TRUE;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002654 clear_tv(rettv);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002655 if (error)
2656 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002657 first = FALSE;
2658 }
2659
2660 /*
2661 * Get the second variable.
2662 */
2663 *arg = skipwhite(*arg + 2);
2664 if (eval3(arg, &var2, evaluate && !result) == FAIL)
2665 return FAIL;
2666
2667 /*
2668 * Compute the result.
2669 */
2670 if (evaluate && !result)
2671 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01002672 if (tv_get_number_chk(&var2, &error) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002673 result = TRUE;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002674 clear_tv(&var2);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002675 if (error)
2676 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002677 }
2678 if (evaluate)
2679 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002680 rettv->v_type = VAR_NUMBER;
2681 rettv->vval.v_number = result;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002682 }
2683 }
2684
2685 return OK;
2686}
2687
2688/*
2689 * Handle second level expression:
2690 * expr3 && expr3 && expr3 logical AND
2691 *
2692 * "arg" must point to the first non-white of the expression.
2693 * "arg" is advanced to the next non-white after the recognized expression.
2694 *
2695 * Return OK or FAIL.
2696 */
2697 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002698eval3(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002699{
Bram Moolenaar33570922005-01-25 22:26:29 +00002700 typval_T var2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002701 long result;
2702 int first;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002703 int error = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002704
2705 /*
2706 * Get the first variable.
2707 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002708 if (eval4(arg, rettv, evaluate) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002709 return FAIL;
2710
2711 /*
2712 * Repeat until there is no following "&&".
2713 */
2714 first = TRUE;
2715 result = TRUE;
2716 while ((*arg)[0] == '&' && (*arg)[1] == '&')
2717 {
2718 if (evaluate && first)
2719 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01002720 if (tv_get_number_chk(rettv, &error) == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002721 result = FALSE;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002722 clear_tv(rettv);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002723 if (error)
2724 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002725 first = FALSE;
2726 }
2727
2728 /*
2729 * Get the second variable.
2730 */
2731 *arg = skipwhite(*arg + 2);
2732 if (eval4(arg, &var2, evaluate && result) == FAIL)
2733 return FAIL;
2734
2735 /*
2736 * Compute the result.
2737 */
2738 if (evaluate && result)
2739 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01002740 if (tv_get_number_chk(&var2, &error) == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002741 result = FALSE;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002742 clear_tv(&var2);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002743 if (error)
2744 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002745 }
2746 if (evaluate)
2747 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002748 rettv->v_type = VAR_NUMBER;
2749 rettv->vval.v_number = result;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002750 }
2751 }
2752
2753 return OK;
2754}
2755
2756/*
2757 * Handle third level expression:
2758 * var1 == var2
2759 * var1 =~ var2
2760 * var1 != var2
2761 * var1 !~ var2
2762 * var1 > var2
2763 * var1 >= var2
2764 * var1 < var2
2765 * var1 <= var2
Bram Moolenaar8a283e52005-01-06 23:28:25 +00002766 * var1 is var2
2767 * var1 isnot var2
Bram Moolenaar071d4272004-06-13 20:20:40 +00002768 *
2769 * "arg" must point to the first non-white of the expression.
2770 * "arg" is advanced to the next non-white after the recognized expression.
2771 *
2772 * Return OK or FAIL.
2773 */
2774 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002775eval4(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002776{
Bram Moolenaar33570922005-01-25 22:26:29 +00002777 typval_T var2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002778 char_u *p;
2779 int i;
2780 exptype_T type = TYPE_UNKNOWN;
Bram Moolenaar8a283e52005-01-06 23:28:25 +00002781 int type_is = FALSE; /* TRUE for "is" and "isnot" */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002782 int len = 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002783 int ic;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002784
2785 /*
2786 * Get the first variable.
2787 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002788 if (eval5(arg, rettv, evaluate) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002789 return FAIL;
2790
2791 p = *arg;
2792 switch (p[0])
2793 {
2794 case '=': if (p[1] == '=')
2795 type = TYPE_EQUAL;
2796 else if (p[1] == '~')
2797 type = TYPE_MATCH;
2798 break;
2799 case '!': if (p[1] == '=')
2800 type = TYPE_NEQUAL;
2801 else if (p[1] == '~')
2802 type = TYPE_NOMATCH;
2803 break;
2804 case '>': if (p[1] != '=')
2805 {
2806 type = TYPE_GREATER;
2807 len = 1;
2808 }
2809 else
2810 type = TYPE_GEQUAL;
2811 break;
2812 case '<': if (p[1] != '=')
2813 {
2814 type = TYPE_SMALLER;
2815 len = 1;
2816 }
2817 else
2818 type = TYPE_SEQUAL;
2819 break;
Bram Moolenaar8a283e52005-01-06 23:28:25 +00002820 case 'i': if (p[1] == 's')
2821 {
2822 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
2823 len = 5;
Bram Moolenaar37a8de12015-09-01 16:05:00 +02002824 i = p[len];
2825 if (!isalnum(i) && i != '_')
Bram Moolenaar8a283e52005-01-06 23:28:25 +00002826 {
2827 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
2828 type_is = TRUE;
2829 }
2830 }
2831 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002832 }
2833
2834 /*
Bram Moolenaar8c8de832008-06-24 22:58:06 +00002835 * If there is a comparative operator, use it.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002836 */
2837 if (type != TYPE_UNKNOWN)
2838 {
2839 /* extra question mark appended: ignore case */
2840 if (p[len] == '?')
2841 {
2842 ic = TRUE;
2843 ++len;
2844 }
2845 /* extra '#' appended: match case */
2846 else if (p[len] == '#')
2847 {
2848 ic = FALSE;
2849 ++len;
2850 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00002851 /* nothing appended: use 'ignorecase' */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002852 else
2853 ic = p_ic;
2854
2855 /*
2856 * Get the second variable.
2857 */
2858 *arg = skipwhite(p + len);
2859 if (eval5(arg, &var2, evaluate) == FAIL)
2860 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002861 clear_tv(rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002862 return FAIL;
2863 }
Bram Moolenaar31988702018-02-13 12:57:42 +01002864 if (evaluate)
2865 {
2866 int ret = typval_compare(rettv, &var2, type, type_is, ic);
2867
2868 clear_tv(&var2);
2869 return ret;
2870 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002871 }
2872
2873 return OK;
2874}
2875
2876/*
2877 * Handle fourth level expression:
2878 * + number addition
2879 * - number subtraction
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02002880 * . string concatenation (if script version is 1)
Bram Moolenaar0f248b02019-04-04 15:36:05 +02002881 * .. string concatenation
Bram Moolenaar071d4272004-06-13 20:20:40 +00002882 *
2883 * "arg" must point to the first non-white of the expression.
2884 * "arg" is advanced to the next non-white after the recognized expression.
2885 *
2886 * Return OK or FAIL.
2887 */
2888 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01002889eval5(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002890{
Bram Moolenaar33570922005-01-25 22:26:29 +00002891 typval_T var2;
2892 typval_T var3;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002893 int op;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02002894 varnumber_T n1, n2;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00002895#ifdef FEAT_FLOAT
2896 float_T f1 = 0, f2 = 0;
2897#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002898 char_u *s1, *s2;
2899 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
2900 char_u *p;
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02002901 int concat;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002902
2903 /*
2904 * Get the first variable.
2905 */
Bram Moolenaar8d00f9c2008-06-28 13:09:56 +00002906 if (eval6(arg, rettv, evaluate, FALSE) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002907 return FAIL;
2908
2909 /*
2910 * Repeat computing, until no '+', '-' or '.' is following.
2911 */
2912 for (;;)
2913 {
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02002914 // "." is only string concatenation when scriptversion is 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00002915 op = **arg;
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02002916 concat = op == '.'
2917 && (*(*arg + 1) == '.' || current_sctx.sc_version < 2);
2918 if (op != '+' && op != '-' && !concat)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002919 break;
2920
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002921 if ((op != '+' || (rettv->v_type != VAR_LIST
2922 && rettv->v_type != VAR_BLOB))
Bram Moolenaar8c8de832008-06-24 22:58:06 +00002923#ifdef FEAT_FLOAT
2924 && (op == '.' || rettv->v_type != VAR_FLOAT)
2925#endif
2926 )
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002927 {
2928 /* For "list + ...", an illegal use of the first operand as
2929 * a number cannot be determined before evaluating the 2nd
2930 * operand: if this is also a list, all is ok.
2931 * For "something . ...", "something - ..." or "non-list + ...",
2932 * we know that the first operand needs to be a string or number
2933 * without evaluating the 2nd operand. So check before to avoid
2934 * side effects after an error. */
Bram Moolenaard155d7a2018-12-21 16:04:21 +01002935 if (evaluate && tv_get_string_chk(rettv) == NULL)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002936 {
2937 clear_tv(rettv);
2938 return FAIL;
2939 }
2940 }
2941
Bram Moolenaar071d4272004-06-13 20:20:40 +00002942 /*
2943 * Get the second variable.
2944 */
Bram Moolenaar0f248b02019-04-04 15:36:05 +02002945 if (op == '.' && *(*arg + 1) == '.') // .. string concatenation
2946 ++*arg;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002947 *arg = skipwhite(*arg + 1);
Bram Moolenaar8d00f9c2008-06-28 13:09:56 +00002948 if (eval6(arg, &var2, evaluate, op == '.') == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002949 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002950 clear_tv(rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002951 return FAIL;
2952 }
2953
2954 if (evaluate)
2955 {
2956 /*
2957 * Compute the result.
2958 */
2959 if (op == '.')
2960 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01002961 s1 = tv_get_string_buf(rettv, buf1); /* already checked */
2962 s2 = tv_get_string_buf_chk(&var2, buf2);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00002963 if (s2 == NULL) /* type error ? */
2964 {
2965 clear_tv(rettv);
2966 clear_tv(&var2);
2967 return FAIL;
2968 }
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00002969 p = concat_str(s1, s2);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00002970 clear_tv(rettv);
2971 rettv->v_type = VAR_STRING;
2972 rettv->vval.v_string = p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002973 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01002974 else if (op == '+' && rettv->v_type == VAR_BLOB
2975 && var2.v_type == VAR_BLOB)
2976 {
2977 blob_T *b1 = rettv->vval.v_blob;
2978 blob_T *b2 = var2.vval.v_blob;
2979 blob_T *b = blob_alloc();
2980 int i;
2981
2982 if (b != NULL)
2983 {
2984 for (i = 0; i < blob_len(b1); i++)
2985 ga_append(&b->bv_ga, blob_get(b1, i));
2986 for (i = 0; i < blob_len(b2); i++)
2987 ga_append(&b->bv_ga, blob_get(b2, i));
2988
2989 clear_tv(rettv);
2990 rettv_blob_set(rettv, b);
2991 }
2992 }
Bram Moolenaare9a41262005-01-15 22:18:47 +00002993 else if (op == '+' && rettv->v_type == VAR_LIST
2994 && var2.v_type == VAR_LIST)
Bram Moolenaar8a283e52005-01-06 23:28:25 +00002995 {
2996 /* concatenate Lists */
2997 if (list_concat(rettv->vval.v_list, var2.vval.v_list,
2998 &var3) == FAIL)
2999 {
3000 clear_tv(rettv);
3001 clear_tv(&var2);
3002 return FAIL;
3003 }
3004 clear_tv(rettv);
3005 *rettv = var3;
3006 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003007 else
3008 {
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003009 int error = FALSE;
3010
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003011#ifdef FEAT_FLOAT
3012 if (rettv->v_type == VAR_FLOAT)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003013 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003014 f1 = rettv->vval.v_float;
3015 n1 = 0;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003016 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003017 else
3018#endif
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003019 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003020 n1 = tv_get_number_chk(rettv, &error);
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003021 if (error)
3022 {
3023 /* This can only happen for "list + non-list". For
3024 * "non-list + ..." or "something - ...", we returned
3025 * before evaluating the 2nd operand. */
3026 clear_tv(rettv);
3027 return FAIL;
3028 }
3029#ifdef FEAT_FLOAT
3030 if (var2.v_type == VAR_FLOAT)
3031 f1 = n1;
3032#endif
3033 }
3034#ifdef FEAT_FLOAT
3035 if (var2.v_type == VAR_FLOAT)
3036 {
3037 f2 = var2.vval.v_float;
3038 n2 = 0;
3039 }
3040 else
3041#endif
3042 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003043 n2 = tv_get_number_chk(&var2, &error);
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003044 if (error)
3045 {
3046 clear_tv(rettv);
3047 clear_tv(&var2);
3048 return FAIL;
3049 }
3050#ifdef FEAT_FLOAT
3051 if (rettv->v_type == VAR_FLOAT)
3052 f2 = n2;
3053#endif
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003054 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003055 clear_tv(rettv);
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003056
3057#ifdef FEAT_FLOAT
3058 /* If there is a float on either side the result is a float. */
3059 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
3060 {
3061 if (op == '+')
3062 f1 = f1 + f2;
3063 else
3064 f1 = f1 - f2;
3065 rettv->v_type = VAR_FLOAT;
3066 rettv->vval.v_float = f1;
3067 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003068 else
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003069#endif
3070 {
3071 if (op == '+')
3072 n1 = n1 + n2;
3073 else
3074 n1 = n1 - n2;
3075 rettv->v_type = VAR_NUMBER;
3076 rettv->vval.v_number = n1;
3077 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003078 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003079 clear_tv(&var2);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003080 }
3081 }
3082 return OK;
3083}
3084
3085/*
3086 * Handle fifth level expression:
3087 * * number multiplication
3088 * / number division
3089 * % number modulo
3090 *
3091 * "arg" must point to the first non-white of the expression.
3092 * "arg" is advanced to the next non-white after the recognized expression.
3093 *
3094 * Return OK or FAIL.
3095 */
3096 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01003097eval6(
3098 char_u **arg,
3099 typval_T *rettv,
3100 int evaluate,
3101 int want_string) /* after "." operator */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003102{
Bram Moolenaar33570922005-01-25 22:26:29 +00003103 typval_T var2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003104 int op;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02003105 varnumber_T n1, n2;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003106#ifdef FEAT_FLOAT
3107 int use_float = FALSE;
Bram Moolenaar1f3601e2019-04-26 20:33:00 +02003108 float_T f1 = 0, f2 = 0;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003109#endif
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003110 int error = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003111
3112 /*
3113 * Get the first variable.
3114 */
Bram Moolenaar8d00f9c2008-06-28 13:09:56 +00003115 if (eval7(arg, rettv, evaluate, want_string) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003116 return FAIL;
3117
3118 /*
3119 * Repeat computing, until no '*', '/' or '%' is following.
3120 */
3121 for (;;)
3122 {
3123 op = **arg;
Bram Moolenaarb8be54d2019-07-14 18:22:59 +02003124 if (op != '*' && op != '/' && op != '%')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003125 break;
3126
3127 if (evaluate)
3128 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003129#ifdef FEAT_FLOAT
3130 if (rettv->v_type == VAR_FLOAT)
3131 {
3132 f1 = rettv->vval.v_float;
3133 use_float = TRUE;
3134 n1 = 0;
3135 }
3136 else
3137#endif
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003138 n1 = tv_get_number_chk(rettv, &error);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003139 clear_tv(rettv);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003140 if (error)
3141 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003142 }
3143 else
3144 n1 = 0;
3145
3146 /*
3147 * Get the second variable.
3148 */
3149 *arg = skipwhite(*arg + 1);
Bram Moolenaar8d00f9c2008-06-28 13:09:56 +00003150 if (eval7(arg, &var2, evaluate, FALSE) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003151 return FAIL;
3152
3153 if (evaluate)
3154 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003155#ifdef FEAT_FLOAT
3156 if (var2.v_type == VAR_FLOAT)
3157 {
3158 if (!use_float)
3159 {
3160 f1 = n1;
3161 use_float = TRUE;
3162 }
3163 f2 = var2.vval.v_float;
3164 n2 = 0;
3165 }
3166 else
3167#endif
3168 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003169 n2 = tv_get_number_chk(&var2, &error);
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003170 clear_tv(&var2);
3171 if (error)
3172 return FAIL;
3173#ifdef FEAT_FLOAT
3174 if (use_float)
3175 f2 = n2;
3176#endif
3177 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003178
3179 /*
3180 * Compute the result.
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003181 * When either side is a float the result is a float.
Bram Moolenaar071d4272004-06-13 20:20:40 +00003182 */
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003183#ifdef FEAT_FLOAT
3184 if (use_float)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003185 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003186 if (op == '*')
3187 f1 = f1 * f2;
3188 else if (op == '/')
3189 {
Bram Moolenaarf878bcf2010-07-30 22:29:41 +02003190# ifdef VMS
3191 /* VMS crashes on divide by zero, work around it */
3192 if (f2 == 0.0)
3193 {
3194 if (f1 == 0)
Bram Moolenaar314f11d2010-08-09 22:07:08 +02003195 f1 = -1 * __F_FLT_MAX - 1L; /* similar to NaN */
Bram Moolenaarf878bcf2010-07-30 22:29:41 +02003196 else if (f1 < 0)
Bram Moolenaar314f11d2010-08-09 22:07:08 +02003197 f1 = -1 * __F_FLT_MAX;
Bram Moolenaarf878bcf2010-07-30 22:29:41 +02003198 else
Bram Moolenaar314f11d2010-08-09 22:07:08 +02003199 f1 = __F_FLT_MAX;
Bram Moolenaarf878bcf2010-07-30 22:29:41 +02003200 }
3201 else
3202 f1 = f1 / f2;
3203# else
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003204 /* We rely on the floating point library to handle divide
3205 * by zero to result in "inf" and not a crash. */
3206 f1 = f1 / f2;
Bram Moolenaarf878bcf2010-07-30 22:29:41 +02003207# endif
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003208 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003209 else
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003210 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003211 emsg(_("E804: Cannot use '%' with Float"));
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003212 return FAIL;
3213 }
3214 rettv->v_type = VAR_FLOAT;
3215 rettv->vval.v_float = f1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003216 }
3217 else
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003218#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003219 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003220 if (op == '*')
3221 n1 = n1 * n2;
3222 else if (op == '/')
Bram Moolenaare21c1582019-03-02 11:57:09 +01003223 n1 = num_divide(n1, n2);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003224 else
Bram Moolenaare21c1582019-03-02 11:57:09 +01003225 n1 = num_modulus(n1, n2);
3226
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003227 rettv->v_type = VAR_NUMBER;
3228 rettv->vval.v_number = n1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003229 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003230 }
3231 }
3232
3233 return OK;
3234}
3235
3236/*
3237 * Handle sixth level expression:
3238 * number number constant
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003239 * 0zFFFFFFFF Blob constant
Bram Moolenaarbae0c162007-05-10 19:30:25 +00003240 * "string" string constant
3241 * 'string' literal string constant
Bram Moolenaar071d4272004-06-13 20:20:40 +00003242 * &option-name option value
3243 * @r register contents
3244 * identifier variable value
3245 * function() function call
3246 * $VAR environment variable
3247 * (expression) nested expression
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00003248 * [expr, expr] List
Bram Moolenaard5abb4c2019-07-13 22:46:10 +02003249 * {key: val, key: val} Dictionary
Bram Moolenaar4c6d9042019-07-16 22:04:02 +02003250 * #{key: val, key: val} Dictionary with literal keys
Bram Moolenaar071d4272004-06-13 20:20:40 +00003251 *
3252 * Also handle:
3253 * ! in front logical NOT
3254 * - in front unary minus
3255 * + in front unary plus (ignored)
Bram Moolenaar8c711452005-01-14 21:53:12 +00003256 * trailing [] subscript in String or List
3257 * trailing .name entry in Dictionary
Bram Moolenaarac92e252019-08-03 21:58:38 +02003258 * trailing ->name() method call
Bram Moolenaar071d4272004-06-13 20:20:40 +00003259 *
3260 * "arg" must point to the first non-white of the expression.
3261 * "arg" is advanced to the next non-white after the recognized expression.
3262 *
3263 * Return OK or FAIL.
3264 */
3265 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01003266eval7(
3267 char_u **arg,
3268 typval_T *rettv,
3269 int evaluate,
3270 int want_string UNUSED) /* after "." operator */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003271{
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02003272 varnumber_T n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003273 int len;
3274 char_u *s;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003275 char_u *start_leader, *end_leader;
3276 int ret = OK;
3277 char_u *alias;
3278
3279 /*
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003280 * Initialise variable so that clear_tv() can't mistake this for a
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003281 * string and free a string that isn't there.
Bram Moolenaar071d4272004-06-13 20:20:40 +00003282 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003283 rettv->v_type = VAR_UNKNOWN;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003284
3285 /*
Bram Moolenaaredf3f972016-08-29 22:49:24 +02003286 * Skip '!', '-' and '+' characters. They are handled later.
Bram Moolenaar071d4272004-06-13 20:20:40 +00003287 */
3288 start_leader = *arg;
3289 while (**arg == '!' || **arg == '-' || **arg == '+')
3290 *arg = skipwhite(*arg + 1);
3291 end_leader = *arg;
3292
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02003293 if (**arg == '.' && (!isdigit(*(*arg + 1))
3294#ifdef FEAT_FLOAT
3295 || current_sctx.sc_version < 2
3296#endif
3297 ))
3298 {
3299 semsg(_(e_invexpr2), *arg);
3300 ++*arg;
3301 return FAIL;
3302 }
3303
Bram Moolenaar071d4272004-06-13 20:20:40 +00003304 switch (**arg)
3305 {
3306 /*
3307 * Number constant.
3308 */
3309 case '0':
3310 case '1':
3311 case '2':
3312 case '3':
3313 case '4':
3314 case '5':
3315 case '6':
3316 case '7':
3317 case '8':
3318 case '9':
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02003319 case '.':
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003320 {
3321#ifdef FEAT_FLOAT
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02003322 char_u *p;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003323 int get_float = FALSE;
3324
3325 /* We accept a float when the format matches
3326 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
Bram Moolenaar8d00f9c2008-06-28 13:09:56 +00003327 * strict to avoid backwards compatibility problems.
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02003328 * With script version 2 and later the leading digit can be
3329 * omitted.
Bram Moolenaar8d00f9c2008-06-28 13:09:56 +00003330 * Don't look for a float after the "." operator, so that
3331 * ":let vers = 1.2.3" doesn't fail. */
Bram Moolenaar558ca4a2019-04-04 18:15:38 +02003332 if (**arg == '.')
3333 p = *arg;
3334 else
3335 p = skipdigits(*arg + 1);
Bram Moolenaar8d00f9c2008-06-28 13:09:56 +00003336 if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
Bram Moolenaar071d4272004-06-13 20:20:40 +00003337 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003338 get_float = TRUE;
3339 p = skipdigits(p + 2);
3340 if (*p == 'e' || *p == 'E')
3341 {
3342 ++p;
3343 if (*p == '-' || *p == '+')
3344 ++p;
3345 if (!vim_isdigit(*p))
3346 get_float = FALSE;
3347 else
3348 p = skipdigits(p + 1);
3349 }
3350 if (ASCII_ISALPHA(*p) || *p == '.')
3351 get_float = FALSE;
3352 }
3353 if (get_float)
3354 {
3355 float_T f;
3356
3357 *arg += string2float(*arg, &f);
3358 if (evaluate)
3359 {
3360 rettv->v_type = VAR_FLOAT;
3361 rettv->vval.v_float = f;
3362 }
3363 }
3364 else
3365#endif
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003366 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003367 {
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003368 char_u *bp;
Bram Moolenaare519dfd2019-01-13 15:42:02 +01003369 blob_T *blob = NULL; // init for gcc
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003370
3371 // Blob constant: 0z0123456789abcdef
3372 if (evaluate)
3373 blob = blob_alloc();
3374 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
3375 {
3376 if (!vim_isxdigit(bp[1]))
3377 {
Bram Moolenaarecc8bc42019-01-13 16:07:21 +01003378 if (blob != NULL)
3379 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003380 emsg(_("E973: Blob literal should have an even number of hex characters"));
Bram Moolenaarecc8bc42019-01-13 16:07:21 +01003381 ga_clear(&blob->bv_ga);
3382 VIM_CLEAR(blob);
3383 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003384 ret = FAIL;
3385 break;
3386 }
3387 if (blob != NULL)
3388 ga_append(&blob->bv_ga,
3389 (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
Bram Moolenaar4131fd52019-01-17 16:32:53 +01003390 if (bp[2] == '.' && vim_isxdigit(bp[3]))
3391 ++bp;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003392 }
3393 if (blob != NULL)
Bram Moolenaarecc8bc42019-01-13 16:07:21 +01003394 rettv_blob_set(rettv, blob);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003395 *arg = bp;
3396 }
3397 else
3398 {
3399 // decimal, hex or octal number
Bram Moolenaar16e9b852019-05-19 19:59:35 +02003400 vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0, TRUE);
3401 if (len == 0)
3402 {
3403 semsg(_(e_invexpr2), *arg);
3404 ret = FAIL;
3405 break;
3406 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003407 *arg += len;
3408 if (evaluate)
3409 {
3410 rettv->v_type = VAR_NUMBER;
3411 rettv->vval.v_number = n;
3412 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003413 }
3414 break;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003415 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003416
3417 /*
3418 * String constant: "string".
3419 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003420 case '"': ret = get_string_tv(arg, rettv, evaluate);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003421 break;
3422
3423 /*
Bram Moolenaar8c711452005-01-14 21:53:12 +00003424 * Literal string constant: 'str''ing'.
Bram Moolenaar071d4272004-06-13 20:20:40 +00003425 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003426 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003427 break;
3428
3429 /*
3430 * List: [expr, expr]
3431 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003432 case '[': ret = get_list_tv(arg, rettv, evaluate);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003433 break;
3434
3435 /*
Bram Moolenaar4c6d9042019-07-16 22:04:02 +02003436 * Dictionary: #{key: val, key: val}
Bram Moolenaard5abb4c2019-07-13 22:46:10 +02003437 */
Bram Moolenaar4c6d9042019-07-16 22:04:02 +02003438 case '#': if ((*arg)[1] == '{')
Bram Moolenaard5abb4c2019-07-13 22:46:10 +02003439 {
3440 ++*arg;
3441 ret = dict_get_tv(arg, rettv, evaluate, TRUE);
3442 }
3443 else
3444 ret = NOTDONE;
3445 break;
3446
3447 /*
Bram Moolenaar069c1e72016-07-15 21:25:08 +02003448 * Lambda: {arg, arg -> expr}
Bram Moolenaard5abb4c2019-07-13 22:46:10 +02003449 * Dictionary: {'key': val, 'key': val}
Bram Moolenaar8c711452005-01-14 21:53:12 +00003450 */
Bram Moolenaar069c1e72016-07-15 21:25:08 +02003451 case '{': ret = get_lambda_tv(arg, rettv, evaluate);
3452 if (ret == NOTDONE)
Bram Moolenaard5abb4c2019-07-13 22:46:10 +02003453 ret = dict_get_tv(arg, rettv, evaluate, FALSE);
Bram Moolenaar8c711452005-01-14 21:53:12 +00003454 break;
3455
3456 /*
Bram Moolenaare9a41262005-01-15 22:18:47 +00003457 * Option value: &name
Bram Moolenaar071d4272004-06-13 20:20:40 +00003458 */
Bram Moolenaare9a41262005-01-15 22:18:47 +00003459 case '&': ret = get_option_tv(arg, rettv, evaluate);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003460 break;
3461
3462 /*
3463 * Environment variable: $VAR.
3464 */
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003465 case '$': ret = get_env_tv(arg, rettv, evaluate);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003466 break;
3467
3468 /*
3469 * Register contents: @r.
3470 */
3471 case '@': ++*arg;
3472 if (evaluate)
3473 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003474 rettv->v_type = VAR_STRING;
Bram Moolenaarb7cb42b2014-04-02 19:55:10 +02003475 rettv->vval.v_string = get_reg_contents(**arg,
3476 GREG_EXPR_SRC);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003477 }
3478 if (**arg != NUL)
3479 ++*arg;
3480 break;
3481
3482 /*
3483 * nested expression: (expression).
3484 */
3485 case '(': *arg = skipwhite(*arg + 1);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003486 ret = eval1(arg, rettv, evaluate); /* recursive! */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003487 if (**arg == ')')
3488 ++*arg;
3489 else if (ret == OK)
3490 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003491 emsg(_("E110: Missing ')'"));
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003492 clear_tv(rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003493 ret = FAIL;
3494 }
3495 break;
3496
Bram Moolenaar8c711452005-01-14 21:53:12 +00003497 default: ret = NOTDONE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003498 break;
3499 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00003500
3501 if (ret == NOTDONE)
3502 {
3503 /*
3504 * Must be a variable or function name.
3505 * Can also be a curly-braces kind of name: {expr}.
3506 */
3507 s = *arg;
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00003508 len = get_name_len(arg, &alias, evaluate, TRUE);
Bram Moolenaar8c711452005-01-14 21:53:12 +00003509 if (alias != NULL)
3510 s = alias;
3511
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00003512 if (len <= 0)
Bram Moolenaar8c711452005-01-14 21:53:12 +00003513 ret = FAIL;
3514 else
3515 {
3516 if (**arg == '(') /* recursive! */
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003517 ret = eval_func(arg, s, len, rettv, evaluate, NULL);
Bram Moolenaar8c711452005-01-14 21:53:12 +00003518 else if (evaluate)
Bram Moolenaar1cd5e612015-05-04 11:10:27 +02003519 ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE);
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00003520 else
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02003521 {
3522 check_vars(s, len);
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00003523 ret = OK;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02003524 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00003525 }
Bram Moolenaar3c2d6532011-02-01 13:48:53 +01003526 vim_free(alias);
Bram Moolenaar8c711452005-01-14 21:53:12 +00003527 }
3528
Bram Moolenaar071d4272004-06-13 20:20:40 +00003529 *arg = skipwhite(*arg);
3530
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00003531 /* Handle following '[', '(' and '.' for expr[expr], expr.name,
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +02003532 * expr(expr), expr->name(expr) */
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00003533 if (ret == OK)
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003534 ret = handle_subscript(arg, rettv, evaluate, TRUE,
3535 start_leader, &end_leader);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003536
3537 /*
3538 * Apply logical NOT and unary '-', from right to left, ignore '+'.
3539 */
3540 if (ret == OK && evaluate && end_leader > start_leader)
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003541 ret = eval7_leader(rettv, start_leader, &end_leader);
3542 return ret;
3543}
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003544
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003545/*
3546 * Apply the leading "!" and "-" before an eval7 expression to "rettv".
3547 * Adjusts "end_leaderp" until it is at "start_leader".
3548 */
3549 static int
3550eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp)
3551{
3552 char_u *end_leader = *end_leaderp;
3553 int ret = OK;
3554 int error = FALSE;
3555 varnumber_T val = 0;
3556#ifdef FEAT_FLOAT
3557 float_T f = 0.0;
3558
3559 if (rettv->v_type == VAR_FLOAT)
3560 f = rettv->vval.v_float;
3561 else
Bram Moolenaar8c8de832008-06-24 22:58:06 +00003562#endif
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003563 val = tv_get_number_chk(rettv, &error);
3564 if (error)
3565 {
3566 clear_tv(rettv);
3567 ret = FAIL;
3568 }
3569 else
3570 {
3571 while (end_leader > start_leader)
3572 {
3573 --end_leader;
3574 if (*end_leader == '!')
3575 {
3576#ifdef FEAT_FLOAT
3577 if (rettv->v_type == VAR_FLOAT)
3578 f = !f;
3579 else
3580#endif
3581 val = !val;
3582 }
3583 else if (*end_leader == '-')
3584 {
3585#ifdef FEAT_FLOAT
3586 if (rettv->v_type == VAR_FLOAT)
3587 f = -f;
3588 else
3589#endif
3590 val = -val;
3591 }
3592 }
3593#ifdef FEAT_FLOAT
3594 if (rettv->v_type == VAR_FLOAT)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003595 {
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003596 clear_tv(rettv);
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003597 rettv->vval.v_float = f;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003598 }
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003599 else
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003600#endif
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003601 {
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003602 clear_tv(rettv);
3603 rettv->v_type = VAR_NUMBER;
3604 rettv->vval.v_number = val;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003605 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003606 }
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02003607 *end_leaderp = end_leader;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003608 return ret;
3609}
3610
3611/*
Bram Moolenaar22a0c0c2019-08-09 23:25:08 +02003612 * Call the function referred to in "rettv".
3613 */
3614 static int
3615call_func_rettv(
3616 char_u **arg,
3617 typval_T *rettv,
3618 int evaluate,
3619 dict_T *selfdict,
3620 typval_T *basetv)
3621{
3622 partial_T *pt = NULL;
3623 funcexe_T funcexe;
3624 typval_T functv;
3625 char_u *s;
3626 int ret;
3627
3628 // need to copy the funcref so that we can clear rettv
3629 if (evaluate)
3630 {
3631 functv = *rettv;
3632 rettv->v_type = VAR_UNKNOWN;
3633
3634 /* Invoke the function. Recursive! */
3635 if (functv.v_type == VAR_PARTIAL)
3636 {
3637 pt = functv.vval.v_partial;
3638 s = partial_name(pt);
3639 }
3640 else
3641 s = functv.vval.v_string;
3642 }
3643 else
3644 s = (char_u *)"";
3645
3646 vim_memset(&funcexe, 0, sizeof(funcexe));
3647 funcexe.firstline = curwin->w_cursor.lnum;
3648 funcexe.lastline = curwin->w_cursor.lnum;
3649 funcexe.evaluate = evaluate;
3650 funcexe.partial = pt;
3651 funcexe.selfdict = selfdict;
3652 funcexe.basetv = basetv;
3653 ret = get_func_tv(s, -1, rettv, arg, &funcexe);
3654
3655 /* Clear the funcref afterwards, so that deleting it while
3656 * evaluating the arguments is possible (see test55). */
3657 if (evaluate)
3658 clear_tv(&functv);
3659
3660 return ret;
3661}
3662
3663/*
3664 * Evaluate "->method()".
3665 * "*arg" points to the '-'.
3666 * Returns FAIL or OK. "*arg" is advanced to after the ')'.
3667 */
3668 static int
3669eval_lambda(
3670 char_u **arg,
3671 typval_T *rettv,
3672 int evaluate,
3673 int verbose) /* give error messages */
3674{
3675 typval_T base = *rettv;
3676 int ret;
3677
3678 // Skip over the ->.
3679 *arg += 2;
3680 rettv->v_type = VAR_UNKNOWN;
3681
3682 ret = get_lambda_tv(arg, rettv, evaluate);
3683 if (ret == NOTDONE)
3684 return FAIL;
3685 else if (**arg != '(')
3686 {
3687 if (verbose)
3688 {
3689 if (*skipwhite(*arg) == '(')
3690 semsg(_(e_nowhitespace));
3691 else
3692 semsg(_(e_missingparen), "lambda");
3693 }
3694 clear_tv(rettv);
3695 return FAIL;
3696 }
3697 return call_func_rettv(arg, rettv, evaluate, NULL, &base);
3698}
3699
3700/*
Bram Moolenaarac92e252019-08-03 21:58:38 +02003701 * Evaluate "->method()".
3702 * "*arg" points to the '-'.
3703 * Returns FAIL or OK. "*arg" is advanced to after the ')'.
3704 */
3705 static int
3706eval_method(
3707 char_u **arg,
3708 typval_T *rettv,
3709 int evaluate,
3710 int verbose) /* give error messages */
3711{
3712 char_u *name;
3713 long len;
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003714 char_u *alias;
Bram Moolenaarac92e252019-08-03 21:58:38 +02003715 typval_T base = *rettv;
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003716 int ret;
Bram Moolenaarac92e252019-08-03 21:58:38 +02003717
3718 // Skip over the ->.
3719 *arg += 2;
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003720 rettv->v_type = VAR_UNKNOWN;
Bram Moolenaarac92e252019-08-03 21:58:38 +02003721
Bram Moolenaarac92e252019-08-03 21:58:38 +02003722 name = *arg;
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003723 len = get_name_len(arg, &alias, evaluate, TRUE);
3724 if (alias != NULL)
3725 name = alias;
3726
3727 if (len <= 0)
Bram Moolenaarac92e252019-08-03 21:58:38 +02003728 {
3729 if (verbose)
3730 emsg(_("E260: Missing name after ->"));
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003731 ret = FAIL;
Bram Moolenaarac92e252019-08-03 21:58:38 +02003732 }
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003733 else
Bram Moolenaarac92e252019-08-03 21:58:38 +02003734 {
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003735 if (**arg != '(')
3736 {
3737 if (verbose)
3738 semsg(_(e_missingparen), name);
3739 ret = FAIL;
3740 }
Bram Moolenaar51841322019-08-08 21:10:01 +02003741 else if (VIM_ISWHITE((*arg)[-1]))
3742 {
3743 if (verbose)
Bram Moolenaar22a0c0c2019-08-09 23:25:08 +02003744 semsg(_(e_nowhitespace));
Bram Moolenaar51841322019-08-08 21:10:01 +02003745 ret = FAIL;
3746 }
Bram Moolenaar761fdf02019-08-05 23:10:16 +02003747 else
3748 ret = eval_func(arg, name, len, rettv, evaluate, &base);
Bram Moolenaarac92e252019-08-03 21:58:38 +02003749 }
Bram Moolenaarac92e252019-08-03 21:58:38 +02003750
Bram Moolenaar22a0c0c2019-08-09 23:25:08 +02003751 // Clear the funcref afterwards, so that deleting it while
3752 // evaluating the arguments is possible (see test55).
Bram Moolenaarac92e252019-08-03 21:58:38 +02003753 if (evaluate)
3754 clear_tv(&base);
3755
Bram Moolenaarac92e252019-08-03 21:58:38 +02003756 return ret;
3757}
3758
3759/*
Bram Moolenaar9e54a0e2006-04-14 20:42:25 +00003760 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
3761 * "*arg" points to the '[' or '.'.
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003762 * Returns FAIL or OK. "*arg" is advanced to after the ']'.
3763 */
3764 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01003765eval_index(
3766 char_u **arg,
3767 typval_T *rettv,
3768 int evaluate,
3769 int verbose) /* give error messages */
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003770{
3771 int empty1 = FALSE, empty2 = FALSE;
Bram Moolenaar33570922005-01-25 22:26:29 +00003772 typval_T var1, var2;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003773 long i;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003774 long n1, n2 = 0;
Bram Moolenaar8c711452005-01-14 21:53:12 +00003775 long len = -1;
3776 int range = FALSE;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003777 char_u *s;
Bram Moolenaar8c711452005-01-14 21:53:12 +00003778 char_u *key = NULL;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003779
Bram Moolenaara03f2332016-02-06 18:09:59 +01003780 switch (rettv->v_type)
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003781 {
Bram Moolenaara03f2332016-02-06 18:09:59 +01003782 case VAR_FUNC:
Bram Moolenaar1735bc92016-03-14 23:05:14 +01003783 case VAR_PARTIAL:
Bram Moolenaara03f2332016-02-06 18:09:59 +01003784 if (verbose)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003785 emsg(_("E695: Cannot index a Funcref"));
Bram Moolenaara03f2332016-02-06 18:09:59 +01003786 return FAIL;
3787 case VAR_FLOAT:
Bram Moolenaar2a876e42013-06-12 22:08:58 +02003788#ifdef FEAT_FLOAT
Bram Moolenaara03f2332016-02-06 18:09:59 +01003789 if (verbose)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003790 emsg(_(e_float_as_string));
Bram Moolenaara03f2332016-02-06 18:09:59 +01003791 return FAIL;
Bram Moolenaar2a876e42013-06-12 22:08:58 +02003792#endif
Bram Moolenaara03f2332016-02-06 18:09:59 +01003793 case VAR_SPECIAL:
Bram Moolenaar835dc632016-02-07 14:27:38 +01003794 case VAR_JOB:
Bram Moolenaar77073442016-02-13 23:23:53 +01003795 case VAR_CHANNEL:
Bram Moolenaara03f2332016-02-06 18:09:59 +01003796 if (verbose)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003797 emsg(_("E909: Cannot index a special variable"));
Bram Moolenaara03f2332016-02-06 18:09:59 +01003798 return FAIL;
3799 case VAR_UNKNOWN:
3800 if (evaluate)
3801 return FAIL;
3802 /* FALLTHROUGH */
3803
3804 case VAR_STRING:
3805 case VAR_NUMBER:
3806 case VAR_LIST:
3807 case VAR_DICT:
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003808 case VAR_BLOB:
Bram Moolenaara03f2332016-02-06 18:09:59 +01003809 break;
Bram Moolenaar520e1e42016-01-23 19:46:28 +01003810 }
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003811
Bram Moolenaar0a38dd22015-08-25 16:49:01 +02003812 init_tv(&var1);
3813 init_tv(&var2);
Bram Moolenaar8c711452005-01-14 21:53:12 +00003814 if (**arg == '.')
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003815 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00003816 /*
3817 * dict.name
3818 */
3819 key = *arg + 1;
3820 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
3821 ;
3822 if (len == 0)
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003823 return FAIL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00003824 *arg = skipwhite(key + len);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003825 }
3826 else
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003827 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00003828 /*
3829 * something[idx]
3830 *
3831 * Get the (first) variable from inside the [].
3832 */
3833 *arg = skipwhite(*arg + 1);
3834 if (**arg == ':')
3835 empty1 = TRUE;
3836 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */
3837 return FAIL;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003838 else if (evaluate && tv_get_string_chk(&var1) == NULL)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003839 {
3840 /* not a number or string */
3841 clear_tv(&var1);
3842 return FAIL;
3843 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00003844
3845 /*
3846 * Get the second variable from inside the [:].
3847 */
3848 if (**arg == ':')
3849 {
3850 range = TRUE;
3851 *arg = skipwhite(*arg + 1);
3852 if (**arg == ']')
3853 empty2 = TRUE;
3854 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */
3855 {
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003856 if (!empty1)
3857 clear_tv(&var1);
3858 return FAIL;
3859 }
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003860 else if (evaluate && tv_get_string_chk(&var2) == NULL)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00003861 {
3862 /* not a number or string */
3863 if (!empty1)
3864 clear_tv(&var1);
3865 clear_tv(&var2);
Bram Moolenaar8c711452005-01-14 21:53:12 +00003866 return FAIL;
3867 }
3868 }
3869
3870 /* Check for the ']'. */
3871 if (**arg != ']')
3872 {
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00003873 if (verbose)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003874 emsg(_(e_missbrac));
Bram Moolenaar8c711452005-01-14 21:53:12 +00003875 clear_tv(&var1);
3876 if (range)
3877 clear_tv(&var2);
3878 return FAIL;
3879 }
3880 *arg = skipwhite(*arg + 1); /* skip the ']' */
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003881 }
3882
3883 if (evaluate)
3884 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00003885 n1 = 0;
3886 if (!empty1 && rettv->v_type != VAR_DICT)
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003887 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003888 n1 = tv_get_number(&var1);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003889 clear_tv(&var1);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003890 }
3891 if (range)
3892 {
3893 if (empty2)
3894 n2 = -1;
3895 else
3896 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003897 n2 = tv_get_number(&var2);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003898 clear_tv(&var2);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003899 }
3900 }
3901
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003902 switch (rettv->v_type)
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003903 {
Bram Moolenaar835dc632016-02-07 14:27:38 +01003904 case VAR_UNKNOWN:
Bram Moolenaara03f2332016-02-06 18:09:59 +01003905 case VAR_FUNC:
Bram Moolenaar1735bc92016-03-14 23:05:14 +01003906 case VAR_PARTIAL:
Bram Moolenaara03f2332016-02-06 18:09:59 +01003907 case VAR_FLOAT:
Bram Moolenaar835dc632016-02-07 14:27:38 +01003908 case VAR_SPECIAL:
3909 case VAR_JOB:
Bram Moolenaar77073442016-02-13 23:23:53 +01003910 case VAR_CHANNEL:
Bram Moolenaara03f2332016-02-06 18:09:59 +01003911 break; /* not evaluating, skipping over subscript */
3912
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003913 case VAR_NUMBER:
3914 case VAR_STRING:
Bram Moolenaard155d7a2018-12-21 16:04:21 +01003915 s = tv_get_string(rettv);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003916 len = (long)STRLEN(s);
3917 if (range)
3918 {
3919 /* The resulting variable is a substring. If the indexes
3920 * are out of range the result is empty. */
3921 if (n1 < 0)
3922 {
3923 n1 = len + n1;
3924 if (n1 < 0)
3925 n1 = 0;
3926 }
3927 if (n2 < 0)
3928 n2 = len + n2;
3929 else if (n2 >= len)
3930 n2 = len;
3931 if (n1 >= len || n2 < 0 || n1 > n2)
3932 s = NULL;
3933 else
3934 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));
3935 }
3936 else
3937 {
3938 /* The resulting variable is a string of a single
3939 * character. If the index is too big or negative the
3940 * result is empty. */
3941 if (n1 >= len || n1 < 0)
3942 s = NULL;
3943 else
3944 s = vim_strnsave(s + n1, 1);
3945 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00003946 clear_tv(rettv);
3947 rettv->v_type = VAR_STRING;
3948 rettv->vval.v_string = s;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00003949 break;
3950
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003951 case VAR_BLOB:
3952 len = blob_len(rettv->vval.v_blob);
3953 if (range)
3954 {
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01003955 // The resulting variable is a sub-blob. If the indexes
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01003956 // are out of range the result is empty.
3957 if (n1 < 0)
3958 {
3959 n1 = len + n1;
3960 if (n1 < 0)
3961 n1 = 0;
3962 }
3963 if (n2 < 0)
3964 n2 = len + n2;
3965 else if (n2 >= len)
3966 n2 = len - 1;
3967 if (n1 >= len || n2 < 0 || n1 > n2)
3968 {
3969 clear_tv(rettv);
3970 rettv->v_type = VAR_BLOB;
3971 rettv->vval.v_blob = NULL;
3972 }
3973 else
3974 {
3975 blob_T *blob = blob_alloc();
3976
3977 if (blob != NULL)
3978 {
3979 if (ga_grow(&blob->bv_ga, n2 - n1 + 1) == FAIL)
3980 {
3981 blob_free(blob);
3982 return FAIL;
3983 }
3984 blob->bv_ga.ga_len = n2 - n1 + 1;
3985 for (i = n1; i <= n2; i++)
3986 blob_set(blob, i - n1,
3987 blob_get(rettv->vval.v_blob, i));
3988
3989 clear_tv(rettv);
3990 rettv_blob_set(rettv, blob);
3991 }
3992 }
3993 }
3994 else
3995 {
Bram Moolenaara5be9b62019-01-24 12:31:44 +01003996 // The resulting variable is a byte value.
3997 // If the index is too big or negative that is an error.
3998 if (n1 < 0)
3999 n1 = len + n1;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01004000 if (n1 < len && n1 >= 0)
4001 {
Bram Moolenaara5be9b62019-01-24 12:31:44 +01004002 int v = blob_get(rettv->vval.v_blob, n1);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01004003
4004 clear_tv(rettv);
4005 rettv->v_type = VAR_NUMBER;
4006 rettv->vval.v_number = v;
4007 }
4008 else
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004009 semsg(_(e_blobidx), n1);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01004010 }
4011 break;
4012
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004013 case VAR_LIST:
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004014 len = list_len(rettv->vval.v_list);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004015 if (n1 < 0)
4016 n1 = len + n1;
4017 if (!empty1 && (n1 < 0 || n1 >= len))
4018 {
Bram Moolenaarf9393ef2006-04-24 19:47:27 +00004019 /* For a range we allow invalid values and return an empty
4020 * list. A list index out of range is an error. */
4021 if (!range)
4022 {
4023 if (verbose)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004024 semsg(_(e_listidx), n1);
Bram Moolenaarf9393ef2006-04-24 19:47:27 +00004025 return FAIL;
4026 }
4027 n1 = len;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004028 }
4029 if (range)
4030 {
Bram Moolenaar33570922005-01-25 22:26:29 +00004031 list_T *l;
4032 listitem_T *item;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004033
4034 if (n2 < 0)
4035 n2 = len + n2;
Bram Moolenaar9e54a0e2006-04-14 20:42:25 +00004036 else if (n2 >= len)
4037 n2 = len - 1;
4038 if (!empty2 && (n2 < 0 || n2 + 1 < n1))
Bram Moolenaarf9393ef2006-04-24 19:47:27 +00004039 n2 = -1;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004040 l = list_alloc();
4041 if (l == NULL)
4042 return FAIL;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004043 for (item = list_find(rettv->vval.v_list, n1);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004044 n1 <= n2; ++n1)
4045 {
4046 if (list_append_tv(l, &item->li_tv) == FAIL)
4047 {
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004048 list_free(l);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004049 return FAIL;
4050 }
4051 item = item->li_next;
4052 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004053 clear_tv(rettv);
Bram Moolenaar45cf6e92017-04-30 20:25:19 +02004054 rettv_list_set(rettv, l);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004055 }
4056 else
4057 {
Bram Moolenaarf9393ef2006-04-24 19:47:27 +00004058 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004059 clear_tv(rettv);
4060 *rettv = var1;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004061 }
4062 break;
Bram Moolenaar8c711452005-01-14 21:53:12 +00004063
4064 case VAR_DICT:
4065 if (range)
4066 {
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00004067 if (verbose)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004068 emsg(_(e_dictrange));
Bram Moolenaar8c711452005-01-14 21:53:12 +00004069 if (len == -1)
4070 clear_tv(&var1);
4071 return FAIL;
4072 }
4073 {
Bram Moolenaar33570922005-01-25 22:26:29 +00004074 dictitem_T *item;
Bram Moolenaar8c711452005-01-14 21:53:12 +00004075
4076 if (len == -1)
4077 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01004078 key = tv_get_string_chk(&var1);
Bram Moolenaar0921ecf2016-04-03 22:44:36 +02004079 if (key == NULL)
Bram Moolenaar8c711452005-01-14 21:53:12 +00004080 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004081 clear_tv(&var1);
4082 return FAIL;
4083 }
4084 }
4085
Bram Moolenaarce5e58e2005-01-19 22:24:34 +00004086 item = dict_find(rettv->vval.v_dict, key, (int)len);
Bram Moolenaar8c711452005-01-14 21:53:12 +00004087
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00004088 if (item == NULL && verbose)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004089 semsg(_(e_dictkey), key);
Bram Moolenaar8c711452005-01-14 21:53:12 +00004090 if (len == -1)
4091 clear_tv(&var1);
4092 if (item == NULL)
4093 return FAIL;
4094
4095 copy_tv(&item->di_tv, &var1);
4096 clear_tv(rettv);
4097 *rettv = var1;
4098 }
4099 break;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004100 }
4101 }
4102
Bram Moolenaar49cd9572005-01-03 21:06:01 +00004103 return OK;
4104}
4105
4106/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00004107 * Get an option value.
4108 * "arg" points to the '&' or '+' before the option name.
4109 * "arg" is advanced to character after the option name.
4110 * Return OK or FAIL.
4111 */
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02004112 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004113get_option_tv(
4114 char_u **arg,
4115 typval_T *rettv, /* when NULL, only check if option exists */
4116 int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004117{
4118 char_u *option_end;
4119 long numval;
4120 char_u *stringval;
4121 int opt_type;
4122 int c;
4123 int working = (**arg == '+'); /* has("+option") */
4124 int ret = OK;
4125 int opt_flags;
4126
4127 /*
4128 * Isolate the option name and find its value.
4129 */
4130 option_end = find_option_end(arg, &opt_flags);
4131 if (option_end == NULL)
4132 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004133 if (rettv != NULL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004134 semsg(_("E112: Option name missing: %s"), *arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004135 return FAIL;
4136 }
4137
4138 if (!evaluate)
4139 {
4140 *arg = option_end;
4141 return OK;
4142 }
4143
4144 c = *option_end;
4145 *option_end = NUL;
4146 opt_type = get_option_value(*arg, &numval,
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004147 rettv == NULL ? NULL : &stringval, opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004148
4149 if (opt_type == -3) /* invalid name */
4150 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004151 if (rettv != NULL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004152 semsg(_("E113: Unknown option: %s"), *arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004153 ret = FAIL;
4154 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004155 else if (rettv != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004156 {
4157 if (opt_type == -2) /* hidden string option */
4158 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004159 rettv->v_type = VAR_STRING;
4160 rettv->vval.v_string = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004161 }
4162 else if (opt_type == -1) /* hidden number option */
4163 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004164 rettv->v_type = VAR_NUMBER;
4165 rettv->vval.v_number = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004166 }
4167 else if (opt_type == 1) /* number option */
4168 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004169 rettv->v_type = VAR_NUMBER;
4170 rettv->vval.v_number = numval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004171 }
4172 else /* string option */
4173 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00004174 rettv->v_type = VAR_STRING;
4175 rettv->vval.v_string = stringval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004176 }
4177 }
4178 else if (working && (opt_type == -2 || opt_type == -1))
4179 ret = FAIL;
4180
4181 *option_end = c; /* put back for error messages */
4182 *arg = option_end;
4183
4184 return ret;
4185}
4186
4187/*
4188 * Allocate a variable for a string constant.
4189 * Return OK or FAIL.
4190 */
4191 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004192get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004193{
4194 char_u *p;
4195 char_u *name;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004196 int extra = 0;
4197
4198 /*
4199 * Find the end of the string, skipping backslashed characters.
4200 */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01004201 for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004202 {
4203 if (*p == '\\' && p[1] != NUL)
4204 {
4205 ++p;
4206 /* A "\<x>" form occupies at least 4 characters, and produces up
4207 * to 6 characters: reserve space for 2 extra */
4208 if (*p == '<')
4209 extra += 2;
4210 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004211 }
4212
4213 if (*p != '"')
4214 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004215 semsg(_("E114: Missing quote: %s"), *arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004216 return FAIL;
4217 }
4218
4219 /* If only parsing, set *arg and return here */
4220 if (!evaluate)
4221 {
4222 *arg = p + 1;
4223 return OK;
4224 }
4225
4226 /*
4227 * Copy the string into allocated memory, handling backslashed
4228 * characters.
4229 */
Bram Moolenaar964b3742019-05-24 18:54:09 +02004230 name = alloc(p - *arg + extra);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004231 if (name == NULL)
4232 return FAIL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00004233 rettv->v_type = VAR_STRING;
4234 rettv->vval.v_string = name;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004235
Bram Moolenaar8c711452005-01-14 21:53:12 +00004236 for (p = *arg + 1; *p != NUL && *p != '"'; )
Bram Moolenaar071d4272004-06-13 20:20:40 +00004237 {
4238 if (*p == '\\')
4239 {
4240 switch (*++p)
4241 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004242 case 'b': *name++ = BS; ++p; break;
4243 case 'e': *name++ = ESC; ++p; break;
4244 case 'f': *name++ = FF; ++p; break;
4245 case 'n': *name++ = NL; ++p; break;
4246 case 'r': *name++ = CAR; ++p; break;
4247 case 't': *name++ = TAB; ++p; break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004248
4249 case 'X': /* hex: "\x1", "\x12" */
4250 case 'x':
4251 case 'u': /* Unicode: "\u0023" */
4252 case 'U':
4253 if (vim_isxdigit(p[1]))
4254 {
4255 int n, nr;
4256 int c = toupper(*p);
4257
4258 if (c == 'X')
4259 n = 2;
Bram Moolenaaracc39882015-06-19 12:08:13 +02004260 else if (*p == 'u')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004261 n = 4;
Bram Moolenaaracc39882015-06-19 12:08:13 +02004262 else
4263 n = 8;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004264 nr = 0;
4265 while (--n >= 0 && vim_isxdigit(p[1]))
4266 {
4267 ++p;
4268 nr = (nr << 4) + hex2nr(*p);
4269 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00004270 ++p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004271 /* For "\u" store the number according to
4272 * 'encoding'. */
4273 if (c != 'X')
Bram Moolenaar8c711452005-01-14 21:53:12 +00004274 name += (*mb_char2bytes)(nr, name);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004275 else
Bram Moolenaar8c711452005-01-14 21:53:12 +00004276 *name++ = nr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004277 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004278 break;
4279
4280 /* octal: "\1", "\12", "\123" */
4281 case '0':
4282 case '1':
4283 case '2':
4284 case '3':
4285 case '4':
4286 case '5':
4287 case '6':
Bram Moolenaar8c711452005-01-14 21:53:12 +00004288 case '7': *name = *p++ - '0';
4289 if (*p >= '0' && *p <= '7')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004290 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004291 *name = (*name << 3) + *p++ - '0';
4292 if (*p >= '0' && *p <= '7')
4293 *name = (*name << 3) + *p++ - '0';
Bram Moolenaar071d4272004-06-13 20:20:40 +00004294 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00004295 ++name;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004296 break;
4297
4298 /* Special key, e.g.: "\<C-W>" */
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +02004299 case '<': extra = trans_special(&p, name, TRUE, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004300 if (extra != 0)
4301 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004302 name += extra;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004303 break;
4304 }
4305 /* FALLTHROUGH */
4306
Bram Moolenaar8c711452005-01-14 21:53:12 +00004307 default: MB_COPY_CHAR(p, name);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004308 break;
4309 }
4310 }
4311 else
Bram Moolenaar8c711452005-01-14 21:53:12 +00004312 MB_COPY_CHAR(p, name);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004313
Bram Moolenaar071d4272004-06-13 20:20:40 +00004314 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00004315 *name = NUL;
Bram Moolenaardb249f22016-08-26 16:29:47 +02004316 if (*p != NUL) /* just in case */
4317 ++p;
4318 *arg = p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004319
Bram Moolenaar071d4272004-06-13 20:20:40 +00004320 return OK;
4321}
4322
4323/*
Bram Moolenaar8c711452005-01-14 21:53:12 +00004324 * Allocate a variable for a 'str''ing' constant.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004325 * Return OK or FAIL.
4326 */
4327 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004328get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004329{
4330 char_u *p;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004331 char_u *str;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004332 int reduce = 0;
4333
4334 /*
Bram Moolenaar8c711452005-01-14 21:53:12 +00004335 * Find the end of the string, skipping ''.
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004336 */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01004337 for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004338 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004339 if (*p == '\'')
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004340 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004341 if (p[1] != '\'')
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004342 break;
4343 ++reduce;
4344 ++p;
4345 }
4346 }
4347
Bram Moolenaar8c711452005-01-14 21:53:12 +00004348 if (*p != '\'')
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004349 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004350 semsg(_("E115: Missing quote: %s"), *arg);
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004351 return FAIL;
4352 }
4353
Bram Moolenaar8c711452005-01-14 21:53:12 +00004354 /* If only parsing return after setting "*arg" */
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004355 if (!evaluate)
4356 {
4357 *arg = p + 1;
4358 return OK;
4359 }
4360
4361 /*
Bram Moolenaar8c711452005-01-14 21:53:12 +00004362 * Copy the string into allocated memory, handling '' to ' reduction.
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004363 */
Bram Moolenaar964b3742019-05-24 18:54:09 +02004364 str = alloc((p - *arg) - reduce);
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004365 if (str == NULL)
4366 return FAIL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00004367 rettv->v_type = VAR_STRING;
4368 rettv->vval.v_string = str;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004369
Bram Moolenaar8c711452005-01-14 21:53:12 +00004370 for (p = *arg + 1; *p != NUL; )
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004371 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004372 if (*p == '\'')
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004373 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00004374 if (p[1] != '\'')
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004375 break;
4376 ++p;
4377 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00004378 MB_COPY_CHAR(p, str);
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004379 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00004380 *str = NUL;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004381 *arg = p + 1;
4382
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00004383 return OK;
4384}
4385
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004386/*
4387 * Return the function name of the partial.
4388 */
4389 char_u *
4390partial_name(partial_T *pt)
4391{
4392 if (pt->pt_name != NULL)
4393 return pt->pt_name;
4394 return pt->pt_func->uf_name;
4395}
4396
Bram Moolenaarddecc252016-04-06 22:59:37 +02004397 static void
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004398partial_free(partial_T *pt)
Bram Moolenaarddecc252016-04-06 22:59:37 +02004399{
4400 int i;
4401
4402 for (i = 0; i < pt->pt_argc; ++i)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004403 clear_tv(&pt->pt_argv[i]);
Bram Moolenaarddecc252016-04-06 22:59:37 +02004404 vim_free(pt->pt_argv);
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004405 dict_unref(pt->pt_dict);
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004406 if (pt->pt_name != NULL)
4407 {
4408 func_unref(pt->pt_name);
4409 vim_free(pt->pt_name);
4410 }
4411 else
4412 func_ptr_unref(pt->pt_func);
Bram Moolenaarddecc252016-04-06 22:59:37 +02004413 vim_free(pt);
4414}
4415
4416/*
4417 * Unreference a closure: decrement the reference count and free it when it
4418 * becomes zero.
4419 */
4420 void
4421partial_unref(partial_T *pt)
4422{
4423 if (pt != NULL && --pt->pt_refcount <= 0)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004424 partial_free(pt);
Bram Moolenaarddecc252016-04-06 22:59:37 +02004425}
4426
Bram Moolenaar67b3f992010-11-10 20:41:57 +01004427static int tv_equal_recurse_limit;
4428
Bram Moolenaar8e759ba2016-06-02 17:46:20 +02004429 static int
4430func_equal(
4431 typval_T *tv1,
4432 typval_T *tv2,
4433 int ic) /* ignore case */
4434{
4435 char_u *s1, *s2;
4436 dict_T *d1, *d2;
4437 int a1, a2;
4438 int i;
4439
4440 /* empty and NULL function name considered the same */
4441 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004442 : partial_name(tv1->vval.v_partial);
Bram Moolenaar8e759ba2016-06-02 17:46:20 +02004443 if (s1 != NULL && *s1 == NUL)
4444 s1 = NULL;
4445 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004446 : partial_name(tv2->vval.v_partial);
Bram Moolenaar8e759ba2016-06-02 17:46:20 +02004447 if (s2 != NULL && *s2 == NUL)
4448 s2 = NULL;
4449 if (s1 == NULL || s2 == NULL)
4450 {
4451 if (s1 != s2)
4452 return FALSE;
4453 }
4454 else if (STRCMP(s1, s2) != 0)
4455 return FALSE;
4456
4457 /* empty dict and NULL dict is different */
4458 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
4459 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
4460 if (d1 == NULL || d2 == NULL)
4461 {
4462 if (d1 != d2)
4463 return FALSE;
4464 }
4465 else if (!dict_equal(d1, d2, ic, TRUE))
4466 return FALSE;
4467
4468 /* empty list and no list considered the same */
4469 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
4470 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
4471 if (a1 != a2)
4472 return FALSE;
4473 for (i = 0; i < a1; ++i)
4474 if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
4475 tv2->vval.v_partial->pt_argv + i, ic, TRUE))
4476 return FALSE;
4477
4478 return TRUE;
4479}
4480
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00004481/*
Bram Moolenaar8a283e52005-01-06 23:28:25 +00004482 * Return TRUE if "tv1" and "tv2" have the same value.
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004483 * Compares the items just like "==" would compare them, but strings and
Bram Moolenaar8c8de832008-06-24 22:58:06 +00004484 * numbers are different. Floats and numbers are also different.
Bram Moolenaar8a283e52005-01-06 23:28:25 +00004485 */
Bram Moolenaarcd524592016-07-17 14:57:05 +02004486 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004487tv_equal(
4488 typval_T *tv1,
4489 typval_T *tv2,
4490 int ic, /* ignore case */
4491 int recursive) /* TRUE when used recursively */
Bram Moolenaar8a283e52005-01-06 23:28:25 +00004492{
4493 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00004494 char_u *s1, *s2;
Bram Moolenaar67b3f992010-11-10 20:41:57 +01004495 static int recursive_cnt = 0; /* catch recursive loops */
Bram Moolenaarb47a2402006-10-15 13:09:12 +00004496 int r;
Bram Moolenaar8a283e52005-01-06 23:28:25 +00004497
Bram Moolenaar8b402a02006-10-17 13:16:39 +00004498 /* Catch lists and dicts that have an endless loop by limiting
Bram Moolenaar67b3f992010-11-10 20:41:57 +01004499 * recursiveness to a limit. We guess they are equal then.
4500 * A fixed limit has the problem of still taking an awful long time.
4501 * Reduce the limit every time running into it. That should work fine for
4502 * deeply linked structures that are not recursively linked and catch
4503 * recursiveness quickly. */
4504 if (!recursive)
4505 tv_equal_recurse_limit = 1000;
4506 if (recursive_cnt >= tv_equal_recurse_limit)
4507 {
4508 --tv_equal_recurse_limit;
Bram Moolenaar8b402a02006-10-17 13:16:39 +00004509 return TRUE;
Bram Moolenaar67b3f992010-11-10 20:41:57 +01004510 }
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004511
Bram Moolenaarb33c7eb2016-07-04 22:29:49 +02004512 /* For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and
4513 * arguments. */
Bram Moolenaar8e759ba2016-06-02 17:46:20 +02004514 if ((tv1->v_type == VAR_FUNC
4515 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
4516 && (tv2->v_type == VAR_FUNC
4517 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
4518 {
4519 ++recursive_cnt;
4520 r = func_equal(tv1, tv2, ic);
4521 --recursive_cnt;
4522 return r;
4523 }
4524
4525 if (tv1->v_type != tv2->v_type)
4526 return FALSE;
4527
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004528 switch (tv1->v_type)
Bram Moolenaar8a283e52005-01-06 23:28:25 +00004529 {
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004530 case VAR_LIST:
Bram Moolenaar67b3f992010-11-10 20:41:57 +01004531 ++recursive_cnt;
4532 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
4533 --recursive_cnt;
Bram Moolenaarb47a2402006-10-15 13:09:12 +00004534 return r;
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004535
4536 case VAR_DICT:
Bram Moolenaar67b3f992010-11-10 20:41:57 +01004537 ++recursive_cnt;
4538 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
4539 --recursive_cnt;
Bram Moolenaarb47a2402006-10-15 13:09:12 +00004540 return r;
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004541
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01004542 case VAR_BLOB:
4543 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
4544
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004545 case VAR_NUMBER:
4546 return tv1->vval.v_number == tv2->vval.v_number;
4547
4548 case VAR_STRING:
Bram Moolenaard155d7a2018-12-21 16:04:21 +01004549 s1 = tv_get_string_buf(tv1, buf1);
4550 s2 = tv_get_string_buf(tv2, buf2);
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004551 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
Bram Moolenaar520e1e42016-01-23 19:46:28 +01004552
4553 case VAR_SPECIAL:
4554 return tv1->vval.v_number == tv2->vval.v_number;
Bram Moolenaar835dc632016-02-07 14:27:38 +01004555
4556 case VAR_FLOAT:
4557#ifdef FEAT_FLOAT
4558 return tv1->vval.v_float == tv2->vval.v_float;
4559#endif
4560 case VAR_JOB:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01004561#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar835dc632016-02-07 14:27:38 +01004562 return tv1->vval.v_job == tv2->vval.v_job;
4563#endif
Bram Moolenaar77073442016-02-13 23:23:53 +01004564 case VAR_CHANNEL:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01004565#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar77073442016-02-13 23:23:53 +01004566 return tv1->vval.v_channel == tv2->vval.v_channel;
4567#endif
Bram Moolenaarf0e86a02016-03-19 19:38:12 +01004568 case VAR_FUNC:
4569 case VAR_PARTIAL:
Bram Moolenaar835dc632016-02-07 14:27:38 +01004570 case VAR_UNKNOWN:
4571 break;
Bram Moolenaar8a283e52005-01-06 23:28:25 +00004572 }
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00004573
Bram Moolenaara03f2332016-02-06 18:09:59 +01004574 /* VAR_UNKNOWN can be the result of a invalid expression, let's say it
4575 * does not equal anything, not even itself. */
4576 return FALSE;
Bram Moolenaar8a283e52005-01-06 23:28:25 +00004577}
4578
4579/*
Bram Moolenaar520e1e42016-01-23 19:46:28 +01004580 * Return the next (unique) copy ID.
4581 * Used for serializing nested structures.
4582 */
4583 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004584get_copyID(void)
Bram Moolenaar520e1e42016-01-23 19:46:28 +01004585{
4586 current_copyID += COPYID_INC;
4587 return current_copyID;
4588}
4589
4590/*
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004591 * Garbage collection for lists and dictionaries.
4592 *
4593 * We use reference counts to be able to free most items right away when they
4594 * are no longer used. But for composite items it's possible that it becomes
4595 * unused while the reference count is > 0: When there is a recursive
4596 * reference. Example:
4597 * :let l = [1, 2, 3]
4598 * :let d = {9: l}
4599 * :let l[1] = d
4600 *
4601 * Since this is quite unusual we handle this with garbage collection: every
4602 * once in a while find out which lists and dicts are not referenced from any
4603 * variable.
4604 *
4605 * Here is a good reference text about garbage collection (refers to Python
4606 * but it applies to all reference-counting mechanisms):
4607 * http://python.ca/nas/python/gc/
Bram Moolenaard9fba312005-06-26 22:34:35 +00004608 */
Bram Moolenaard9fba312005-06-26 22:34:35 +00004609
4610/*
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004611 * Do garbage collection for lists and dicts.
Bram Moolenaar574860b2016-05-24 17:33:34 +02004612 * When "testing" is TRUE this is called from test_garbagecollect_now().
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004613 * Return TRUE if some memory was freed.
Bram Moolenaard9fba312005-06-26 22:34:35 +00004614 */
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004615 int
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02004616garbage_collect(int testing)
Bram Moolenaard9fba312005-06-26 22:34:35 +00004617{
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004618 int copyID;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004619 int abort = FALSE;
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004620 buf_T *buf;
4621 win_T *wp;
4622 int i;
Bram Moolenaar934b1362015-02-04 23:06:45 +01004623 int did_free = FALSE;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00004624 tabpage_T *tp;
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004625
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02004626 if (!testing)
4627 {
4628 /* Only do this once. */
4629 want_garbage_collect = FALSE;
4630 may_garbage_collect = FALSE;
4631 garbage_collect_at_exit = FALSE;
4632 }
Bram Moolenaar9fecb462006-09-05 10:59:47 +00004633
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004634 /* We advance by two because we add one for items referenced through
4635 * previous_funccal. */
Bram Moolenaar520e1e42016-01-23 19:46:28 +01004636 copyID = get_copyID();
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004637
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004638 /*
4639 * 1. Go through all accessible variables and mark all lists and dicts
4640 * with copyID.
4641 */
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004642
4643 /* Don't free variables in the previous_funccal list unless they are only
4644 * referenced through previous_funccal. This must be first, because if
Bram Moolenaar2c2398c2009-06-03 11:22:45 +00004645 * the item is referenced elsewhere the funccal must not be freed. */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004646 abort = abort || set_ref_in_previous_funccal(copyID);
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004647
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004648 /* script-local variables */
4649 for (i = 1; i <= ga_scripts.ga_len; ++i)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004650 abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004651
4652 /* buffer-local variables */
Bram Moolenaar29323592016-07-24 22:04:11 +02004653 FOR_ALL_BUFFERS(buf)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004654 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
4655 NULL, NULL);
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004656
4657 /* window-local variables */
Bram Moolenaar910f66f2006-04-05 20:41:53 +00004658 FOR_ALL_TAB_WINDOWS(tp, wp)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004659 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
4660 NULL, NULL);
Bram Moolenaar3bb28552013-04-15 18:25:59 +02004661 if (aucmd_win != NULL)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004662 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID,
4663 NULL, NULL);
Bram Moolenaar4d784b22019-05-25 19:51:39 +02004664#ifdef FEAT_TEXT_PROP
4665 for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
4666 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
4667 NULL, NULL);
Bram Moolenaar4d784b22019-05-25 19:51:39 +02004668 FOR_ALL_TABPAGES(tp)
Bram Moolenaar9c27b1c2019-05-26 18:48:13 +02004669 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
Bram Moolenaar4d784b22019-05-25 19:51:39 +02004670 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
4671 NULL, NULL);
4672#endif
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004673
Bram Moolenaar910f66f2006-04-05 20:41:53 +00004674 /* tabpage-local variables */
Bram Moolenaar29323592016-07-24 22:04:11 +02004675 FOR_ALL_TABPAGES(tp)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004676 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
4677 NULL, NULL);
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004678 /* global variables */
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004679 abort = abort || set_ref_in_ht(&globvarht, copyID, NULL);
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004680
4681 /* function-local variables */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004682 abort = abort || set_ref_in_call_stack(copyID);
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004683
Bram Moolenaarbc7ce672016-08-01 22:49:22 +02004684 /* named functions (matters for closures) */
4685 abort = abort || set_ref_in_functions(copyID);
4686
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02004687 /* function call arguments, if v:testing is set. */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004688 abort = abort || set_ref_in_func_args(copyID);
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02004689
Bram Moolenaard812df62008-11-09 12:46:09 +00004690 /* v: vars */
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004691 abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL);
Bram Moolenaard812df62008-11-09 12:46:09 +00004692
Bram Moolenaar75a1a942019-06-20 03:45:36 +02004693 // callbacks in buffers
4694 abort = abort || set_ref_in_buffers(copyID);
4695
Bram Moolenaar1dced572012-04-05 16:54:08 +02004696#ifdef FEAT_LUA
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004697 abort = abort || set_ref_in_lua(copyID);
Bram Moolenaar1dced572012-04-05 16:54:08 +02004698#endif
4699
Bram Moolenaardb913952012-06-29 12:54:53 +02004700#ifdef FEAT_PYTHON
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004701 abort = abort || set_ref_in_python(copyID);
Bram Moolenaardb913952012-06-29 12:54:53 +02004702#endif
4703
4704#ifdef FEAT_PYTHON3
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004705 abort = abort || set_ref_in_python3(copyID);
Bram Moolenaardb913952012-06-29 12:54:53 +02004706#endif
4707
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01004708#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar3780bb92016-04-12 22:18:53 +02004709 abort = abort || set_ref_in_channel(copyID);
Bram Moolenaarb8d49052016-05-01 14:22:16 +02004710 abort = abort || set_ref_in_job(copyID);
Bram Moolenaar4b6a6dc2016-02-04 22:49:49 +01004711#endif
Bram Moolenaar3266c852016-04-30 18:07:05 +02004712#ifdef FEAT_NETBEANS_INTG
4713 abort = abort || set_ref_in_nb_channel(copyID);
4714#endif
Bram Moolenaar4b6a6dc2016-02-04 22:49:49 +01004715
Bram Moolenaare3188e22016-05-31 21:13:04 +02004716#ifdef FEAT_TIMERS
4717 abort = abort || set_ref_in_timer(copyID);
4718#endif
4719
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02004720#ifdef FEAT_QUICKFIX
4721 abort = abort || set_ref_in_quickfix(copyID);
4722#endif
4723
Bram Moolenaara2c45a12017-07-27 22:14:59 +02004724#ifdef FEAT_TERMINAL
4725 abort = abort || set_ref_in_term(copyID);
4726#endif
4727
Bram Moolenaar75a1a942019-06-20 03:45:36 +02004728#ifdef FEAT_TEXT_PROP
4729 abort = abort || set_ref_in_popups(copyID);
4730#endif
4731
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004732 if (!abort)
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004733 {
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004734 /*
4735 * 2. Free lists and dictionaries that are not referenced.
4736 */
4737 did_free = free_unref_items(copyID);
4738
4739 /*
4740 * 3. Check if any funccal can be freed now.
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004741 * This may call us back recursively.
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004742 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02004743 free_unref_funccal(copyID, testing);
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004744 }
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004745 else if (p_verbose > 0)
4746 {
Bram Moolenaar32526b32019-01-19 17:43:09 +01004747 verb_msg(_("Not enough memory to set references, garbage collection aborted!"));
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004748 }
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004749
4750 return did_free;
4751}
4752
4753/*
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004754 * Free lists, dictionaries, channels and jobs that are no longer referenced.
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004755 */
4756 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004757free_unref_items(int copyID)
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004758{
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00004759 int did_free = FALSE;
4760
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004761 /* Let all "free" functions know that we are here. This means no
4762 * dictionaries, lists, channels or jobs are to be freed, because we will
4763 * do that here. */
4764 in_free_unref_items = TRUE;
4765
4766 /*
4767 * PASS 1: free the contents of the items. We don't free the items
4768 * themselves yet, so that it is possible to decrement refcount counters
4769 */
4770
Bram Moolenaarcd524592016-07-17 14:57:05 +02004771 /* Go through the list of dicts and free items without the copyID. */
4772 did_free |= dict_free_nonref(copyID);
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004773
Bram Moolenaarda861d62016-07-17 15:46:27 +02004774 /* Go through the list of lists and free items without the copyID. */
4775 did_free |= list_free_nonref(copyID);
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004776
4777#ifdef FEAT_JOB_CHANNEL
4778 /* Go through the list of jobs and free items without the copyID. This
4779 * must happen before doing channels, because jobs refer to channels, but
4780 * the reference from the channel to the job isn't tracked. */
4781 did_free |= free_unused_jobs_contents(copyID, COPYID_MASK);
4782
4783 /* Go through the list of channels and free items without the copyID. */
4784 did_free |= free_unused_channels_contents(copyID, COPYID_MASK);
4785#endif
4786
4787 /*
4788 * PASS 2: free the items themselves.
4789 */
Bram Moolenaarcd524592016-07-17 14:57:05 +02004790 dict_free_items(copyID);
Bram Moolenaarda861d62016-07-17 15:46:27 +02004791 list_free_items(copyID);
Bram Moolenaar835dc632016-02-07 14:27:38 +01004792
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004793#ifdef FEAT_JOB_CHANNEL
4794 /* Go through the list of jobs and free items without the copyID. This
4795 * must happen before doing channels, because jobs refer to channels, but
4796 * the reference from the channel to the job isn't tracked. */
4797 free_unused_jobs(copyID, COPYID_MASK);
4798
4799 /* Go through the list of channels and free items without the copyID. */
4800 free_unused_channels(copyID, COPYID_MASK);
4801#endif
4802
4803 in_free_unref_items = FALSE;
4804
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004805 return did_free;
4806}
4807
4808/*
4809 * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004810 * "list_stack" is used to add lists to be marked. Can be NULL.
4811 *
4812 * Returns TRUE if setting references failed somehow.
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004813 */
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004814 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004815set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004816{
4817 int todo;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004818 int abort = FALSE;
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004819 hashitem_T *hi;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004820 hashtab_T *cur_ht;
4821 ht_stack_T *ht_stack = NULL;
4822 ht_stack_T *tempitem;
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004823
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004824 cur_ht = ht;
4825 for (;;)
4826 {
4827 if (!abort)
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004828 {
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004829 /* Mark each item in the hashtab. If the item contains a hashtab
4830 * it is added to ht_stack, if it contains a list it is added to
4831 * list_stack. */
4832 todo = (int)cur_ht->ht_used;
4833 for (hi = cur_ht->ht_array; todo > 0; ++hi)
4834 if (!HASHITEM_EMPTY(hi))
4835 {
4836 --todo;
4837 abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID,
4838 &ht_stack, list_stack);
4839 }
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004840 }
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004841
4842 if (ht_stack == NULL)
4843 break;
4844
4845 /* take an item from the stack */
4846 cur_ht = ht_stack->ht;
4847 tempitem = ht_stack;
4848 ht_stack = ht_stack->prev;
4849 free(tempitem);
4850 }
4851
4852 return abort;
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004853}
4854
4855/*
Bram Moolenaar7be3ab22019-06-23 01:46:15 +02004856 * Mark a dict and its items with "copyID".
4857 * Returns TRUE if setting references failed somehow.
4858 */
4859 int
4860set_ref_in_dict(dict_T *d, int copyID)
4861{
4862 if (d != NULL && d->dv_copyID != copyID)
4863 {
4864 d->dv_copyID = copyID;
4865 return set_ref_in_ht(&d->dv_hashtab, copyID, NULL);
4866 }
4867 return FALSE;
4868}
4869
4870/*
4871 * Mark a list and its items with "copyID".
4872 * Returns TRUE if setting references failed somehow.
4873 */
4874 int
4875set_ref_in_list(list_T *ll, int copyID)
4876{
4877 if (ll != NULL && ll->lv_copyID != copyID)
4878 {
4879 ll->lv_copyID = copyID;
4880 return set_ref_in_list_items(ll, copyID, NULL);
4881 }
4882 return FALSE;
4883}
4884
4885/*
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004886 * Mark all lists and dicts referenced through list "l" with "copyID".
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004887 * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
4888 *
4889 * Returns TRUE if setting references failed somehow.
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004890 */
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004891 int
Bram Moolenaar7be3ab22019-06-23 01:46:15 +02004892set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack)
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004893{
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004894 listitem_T *li;
4895 int abort = FALSE;
4896 list_T *cur_l;
4897 list_stack_T *list_stack = NULL;
4898 list_stack_T *tempitem;
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004899
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004900 cur_l = l;
4901 for (;;)
4902 {
4903 if (!abort)
4904 /* Mark each item in the list. If the item contains a hashtab
4905 * it is added to ht_stack, if it contains a list it is added to
4906 * list_stack. */
4907 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next)
4908 abort = abort || set_ref_in_item(&li->li_tv, copyID,
4909 ht_stack, &list_stack);
4910 if (list_stack == NULL)
4911 break;
4912
4913 /* take an item from the stack */
4914 cur_l = list_stack->list;
4915 tempitem = list_stack;
4916 list_stack = list_stack->prev;
4917 free(tempitem);
4918 }
4919
4920 return abort;
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004921}
4922
4923/*
4924 * Mark all lists and dicts referenced through typval "tv" with "copyID".
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004925 * "list_stack" is used to add lists to be marked. Can be NULL.
4926 * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
4927 *
4928 * Returns TRUE if setting references failed somehow.
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004929 */
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004930 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01004931set_ref_in_item(
4932 typval_T *tv,
4933 int copyID,
4934 ht_stack_T **ht_stack,
4935 list_stack_T **list_stack)
Bram Moolenaar9a50b1b2005-06-27 22:48:21 +00004936{
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004937 int abort = FALSE;
Bram Moolenaard9fba312005-06-26 22:34:35 +00004938
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004939 if (tv->v_type == VAR_DICT)
Bram Moolenaard9fba312005-06-26 22:34:35 +00004940 {
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004941 dict_T *dd = tv->vval.v_dict;
4942
Bram Moolenaara03f2332016-02-06 18:09:59 +01004943 if (dd != NULL && dd->dv_copyID != copyID)
4944 {
4945 /* Didn't see this dict yet. */
4946 dd->dv_copyID = copyID;
4947 if (ht_stack == NULL)
Bram Moolenaard9fba312005-06-26 22:34:35 +00004948 {
Bram Moolenaara03f2332016-02-06 18:09:59 +01004949 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
4950 }
4951 else
4952 {
4953 ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T));
4954 if (newitem == NULL)
4955 abort = TRUE;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004956 else
4957 {
Bram Moolenaara03f2332016-02-06 18:09:59 +01004958 newitem->ht = &dd->dv_hashtab;
4959 newitem->prev = *ht_stack;
4960 *ht_stack = newitem;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004961 }
Bram Moolenaard9fba312005-06-26 22:34:35 +00004962 }
Bram Moolenaara03f2332016-02-06 18:09:59 +01004963 }
4964 }
4965 else if (tv->v_type == VAR_LIST)
4966 {
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004967 list_T *ll = tv->vval.v_list;
4968
Bram Moolenaara03f2332016-02-06 18:09:59 +01004969 if (ll != NULL && ll->lv_copyID != copyID)
4970 {
4971 /* Didn't see this list yet. */
4972 ll->lv_copyID = copyID;
4973 if (list_stack == NULL)
Bram Moolenaard9fba312005-06-26 22:34:35 +00004974 {
Bram Moolenaar7be3ab22019-06-23 01:46:15 +02004975 abort = set_ref_in_list_items(ll, copyID, ht_stack);
Bram Moolenaara03f2332016-02-06 18:09:59 +01004976 }
4977 else
4978 {
4979 list_stack_T *newitem = (list_stack_T*)malloc(
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004980 sizeof(list_stack_T));
Bram Moolenaara03f2332016-02-06 18:09:59 +01004981 if (newitem == NULL)
4982 abort = TRUE;
4983 else
4984 {
4985 newitem->list = ll;
4986 newitem->prev = *list_stack;
4987 *list_stack = newitem;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01004988 }
Bram Moolenaard9fba312005-06-26 22:34:35 +00004989 }
Bram Moolenaara03f2332016-02-06 18:09:59 +01004990 }
Bram Moolenaard9fba312005-06-26 22:34:35 +00004991 }
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02004992 else if (tv->v_type == VAR_FUNC)
4993 {
Bram Moolenaar437bafe2016-08-01 15:40:54 +02004994 abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02004995 }
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02004996 else if (tv->v_type == VAR_PARTIAL)
4997 {
4998 partial_T *pt = tv->vval.v_partial;
4999 int i;
5000
5001 /* A partial does not have a copyID, because it cannot contain itself.
5002 */
5003 if (pt != NULL)
5004 {
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005005 abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02005006
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005007 if (pt->pt_dict != NULL)
5008 {
5009 typval_T dtv;
5010
5011 dtv.v_type = VAR_DICT;
5012 dtv.vval.v_dict = pt->pt_dict;
5013 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5014 }
5015
5016 for (i = 0; i < pt->pt_argc; ++i)
5017 abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
5018 ht_stack, list_stack);
5019 }
5020 }
5021#ifdef FEAT_JOB_CHANNEL
5022 else if (tv->v_type == VAR_JOB)
5023 {
5024 job_T *job = tv->vval.v_job;
5025 typval_T dtv;
5026
5027 if (job != NULL && job->jv_copyID != copyID)
5028 {
Bram Moolenaar0239acb2016-04-11 21:02:54 +02005029 job->jv_copyID = copyID;
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005030 if (job->jv_channel != NULL)
5031 {
5032 dtv.v_type = VAR_CHANNEL;
5033 dtv.vval.v_channel = job->jv_channel;
5034 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5035 }
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005036 if (job->jv_exit_cb.cb_partial != NULL)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005037 {
5038 dtv.v_type = VAR_PARTIAL;
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005039 dtv.vval.v_partial = job->jv_exit_cb.cb_partial;
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005040 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5041 }
5042 }
5043 }
5044 else if (tv->v_type == VAR_CHANNEL)
5045 {
5046 channel_T *ch =tv->vval.v_channel;
Bram Moolenaardc0ccae2016-10-09 17:28:01 +02005047 ch_part_T part;
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005048 typval_T dtv;
5049 jsonq_T *jq;
5050 cbq_T *cq;
5051
5052 if (ch != NULL && ch->ch_copyID != copyID)
5053 {
Bram Moolenaar0239acb2016-04-11 21:02:54 +02005054 ch->ch_copyID = copyID;
Bram Moolenaardc0ccae2016-10-09 17:28:01 +02005055 for (part = PART_SOCK; part < PART_COUNT; ++part)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005056 {
5057 for (jq = ch->ch_part[part].ch_json_head.jq_next; jq != NULL;
5058 jq = jq->jq_next)
5059 set_ref_in_item(jq->jq_value, copyID, ht_stack, list_stack);
5060 for (cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL;
5061 cq = cq->cq_next)
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005062 if (cq->cq_callback.cb_partial != NULL)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005063 {
5064 dtv.v_type = VAR_PARTIAL;
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005065 dtv.vval.v_partial = cq->cq_callback.cb_partial;
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005066 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5067 }
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005068 if (ch->ch_part[part].ch_callback.cb_partial != NULL)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005069 {
5070 dtv.v_type = VAR_PARTIAL;
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005071 dtv.vval.v_partial =
5072 ch->ch_part[part].ch_callback.cb_partial;
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005073 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5074 }
5075 }
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005076 if (ch->ch_callback.cb_partial != NULL)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005077 {
5078 dtv.v_type = VAR_PARTIAL;
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005079 dtv.vval.v_partial = ch->ch_callback.cb_partial;
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005080 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5081 }
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005082 if (ch->ch_close_cb.cb_partial != NULL)
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005083 {
5084 dtv.v_type = VAR_PARTIAL;
Bram Moolenaar3a97bb32019-06-01 13:28:35 +02005085 dtv.vval.v_partial = ch->ch_close_cb.cb_partial;
Bram Moolenaar107e1ee2016-04-08 17:07:19 +02005086 set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5087 }
5088 }
5089 }
5090#endif
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005091 return abort;
Bram Moolenaard9fba312005-06-26 22:34:35 +00005092}
5093
Bram Moolenaar17a13432016-01-24 14:22:10 +01005094 static char *
5095get_var_special_name(int nr)
5096{
5097 switch (nr)
5098 {
Bram Moolenaarf48aa162016-01-24 17:54:24 +01005099 case VVAL_FALSE: return "v:false";
Bram Moolenaar65edff82016-02-21 16:40:11 +01005100 case VVAL_TRUE: return "v:true";
5101 case VVAL_NONE: return "v:none";
5102 case VVAL_NULL: return "v:null";
Bram Moolenaar17a13432016-01-24 14:22:10 +01005103 }
Bram Moolenaar95f09602016-11-10 20:01:45 +01005104 internal_error("get_var_special_name()");
Bram Moolenaar17a13432016-01-24 14:22:10 +01005105 return "42";
5106}
5107
Bram Moolenaar8c711452005-01-14 21:53:12 +00005108/*
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005109 * Return a string with the string representation of a variable.
5110 * If the memory is allocated "tofree" is set to it, otherwise NULL.
Bram Moolenaar8a283e52005-01-06 23:28:25 +00005111 * "numbuf" is used for a number.
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005112 * When "copyID" is not NULL replace recursive lists and dicts with "...".
Bram Moolenaar35422f42017-08-05 16:33:56 +02005113 * When both "echo_style" and "composite_val" are FALSE, put quotes around
5114 * stings as "string()", otherwise does not put quotes around strings, as
5115 * ":echo" displays values.
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005116 * When "restore_copyID" is FALSE, repeated items in dictionaries and lists
5117 * are replaced with "...".
Bram Moolenaar92c5aba2007-08-14 20:29:31 +00005118 * May return NULL.
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005119 */
Bram Moolenaarcd524592016-07-17 14:57:05 +02005120 char_u *
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005121echo_string_core(
Bram Moolenaar7454a062016-01-30 15:14:10 +01005122 typval_T *tv,
5123 char_u **tofree,
5124 char_u *numbuf,
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005125 int copyID,
5126 int echo_style,
5127 int restore_copyID,
Bram Moolenaar35422f42017-08-05 16:33:56 +02005128 int composite_val)
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005129{
Bram Moolenaare9a41262005-01-15 22:18:47 +00005130 static int recurse = 0;
5131 char_u *r = NULL;
5132
Bram Moolenaar33570922005-01-25 22:26:29 +00005133 if (recurse >= DICT_MAXNEST)
Bram Moolenaare9a41262005-01-15 22:18:47 +00005134 {
Bram Moolenaar8502c702014-06-17 12:51:16 +02005135 if (!did_echo_string_emsg)
5136 {
5137 /* Only give this message once for a recursive call to avoid
5138 * flooding the user with errors. And stop iterating over lists
5139 * and dicts. */
5140 did_echo_string_emsg = TRUE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005141 emsg(_("E724: variable nested too deep for displaying"));
Bram Moolenaar8502c702014-06-17 12:51:16 +02005142 }
Bram Moolenaare9a41262005-01-15 22:18:47 +00005143 *tofree = NULL;
Bram Moolenaar8502c702014-06-17 12:51:16 +02005144 return (char_u *)"{E724}";
Bram Moolenaare9a41262005-01-15 22:18:47 +00005145 }
5146 ++recurse;
5147
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005148 switch (tv->v_type)
5149 {
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005150 case VAR_STRING:
Bram Moolenaar35422f42017-08-05 16:33:56 +02005151 if (echo_style && !composite_val)
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005152 {
5153 *tofree = NULL;
Bram Moolenaar35422f42017-08-05 16:33:56 +02005154 r = tv->vval.v_string;
5155 if (r == NULL)
5156 r = (char_u *)"";
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005157 }
5158 else
5159 {
5160 *tofree = string_quote(tv->vval.v_string, FALSE);
5161 r = *tofree;
5162 }
5163 break;
5164
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005165 case VAR_FUNC:
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005166 if (echo_style)
5167 {
5168 *tofree = NULL;
5169 r = tv->vval.v_string;
5170 }
5171 else
5172 {
5173 *tofree = string_quote(tv->vval.v_string, TRUE);
5174 r = *tofree;
5175 }
Bram Moolenaare9a41262005-01-15 22:18:47 +00005176 break;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005177
Bram Moolenaar1735bc92016-03-14 23:05:14 +01005178 case VAR_PARTIAL:
Bram Moolenaar24c77a12016-03-24 21:23:06 +01005179 {
5180 partial_T *pt = tv->vval.v_partial;
5181 char_u *fname = string_quote(pt == NULL ? NULL
Bram Moolenaar437bafe2016-08-01 15:40:54 +02005182 : partial_name(pt), FALSE);
Bram Moolenaar24c77a12016-03-24 21:23:06 +01005183 garray_T ga;
5184 int i;
5185 char_u *tf;
5186
5187 ga_init2(&ga, 1, 100);
5188 ga_concat(&ga, (char_u *)"function(");
5189 if (fname != NULL)
5190 {
5191 ga_concat(&ga, fname);
5192 vim_free(fname);
5193 }
5194 if (pt != NULL && pt->pt_argc > 0)
5195 {
5196 ga_concat(&ga, (char_u *)", [");
5197 for (i = 0; i < pt->pt_argc; ++i)
5198 {
5199 if (i > 0)
5200 ga_concat(&ga, (char_u *)", ");
5201 ga_concat(&ga,
5202 tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
5203 vim_free(tf);
5204 }
5205 ga_concat(&ga, (char_u *)"]");
5206 }
5207 if (pt != NULL && pt->pt_dict != NULL)
5208 {
5209 typval_T dtv;
5210
5211 ga_concat(&ga, (char_u *)", ");
5212 dtv.v_type = VAR_DICT;
5213 dtv.vval.v_dict = pt->pt_dict;
5214 ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
5215 vim_free(tf);
5216 }
5217 ga_concat(&ga, (char_u *)")");
5218
5219 *tofree = ga.ga_data;
5220 r = *tofree;
5221 break;
5222 }
Bram Moolenaar1735bc92016-03-14 23:05:14 +01005223
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01005224 case VAR_BLOB:
Bram Moolenaar8c8b8bb2019-01-13 17:48:04 +01005225 r = blob2string(tv->vval.v_blob, tofree, numbuf);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01005226 break;
5227
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005228 case VAR_LIST:
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005229 if (tv->vval.v_list == NULL)
5230 {
5231 *tofree = NULL;
5232 r = NULL;
5233 }
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005234 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID
5235 && tv->vval.v_list->lv_len > 0)
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005236 {
5237 *tofree = NULL;
5238 r = (char_u *)"[...]";
5239 }
5240 else
5241 {
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005242 int old_copyID = tv->vval.v_list->lv_copyID;
5243
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005244 tv->vval.v_list->lv_copyID = copyID;
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005245 *tofree = list2string(tv, copyID, restore_copyID);
5246 if (restore_copyID)
5247 tv->vval.v_list->lv_copyID = old_copyID;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005248 r = *tofree;
5249 }
Bram Moolenaare9a41262005-01-15 22:18:47 +00005250 break;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005251
Bram Moolenaar8c711452005-01-14 21:53:12 +00005252 case VAR_DICT:
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005253 if (tv->vval.v_dict == NULL)
5254 {
5255 *tofree = NULL;
5256 r = NULL;
5257 }
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005258 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID
5259 && tv->vval.v_dict->dv_hashtab.ht_used != 0)
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005260 {
5261 *tofree = NULL;
5262 r = (char_u *)"{...}";
5263 }
5264 else
5265 {
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005266 int old_copyID = tv->vval.v_dict->dv_copyID;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005267 tv->vval.v_dict->dv_copyID = copyID;
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005268 *tofree = dict2string(tv, copyID, restore_copyID);
5269 if (restore_copyID)
5270 tv->vval.v_dict->dv_copyID = old_copyID;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005271 r = *tofree;
5272 }
Bram Moolenaare9a41262005-01-15 22:18:47 +00005273 break;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005274
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005275 case VAR_NUMBER:
Bram Moolenaara03f2332016-02-06 18:09:59 +01005276 case VAR_UNKNOWN:
Bram Moolenaar35422f42017-08-05 16:33:56 +02005277 *tofree = NULL;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01005278 r = tv_get_string_buf(tv, numbuf);
Bram Moolenaar35422f42017-08-05 16:33:56 +02005279 break;
5280
Bram Moolenaar835dc632016-02-07 14:27:38 +01005281 case VAR_JOB:
Bram Moolenaar77073442016-02-13 23:23:53 +01005282 case VAR_CHANNEL:
Bram Moolenaare9a41262005-01-15 22:18:47 +00005283 *tofree = NULL;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01005284 r = tv_get_string_buf(tv, numbuf);
Bram Moolenaar35422f42017-08-05 16:33:56 +02005285 if (composite_val)
5286 {
5287 *tofree = string_quote(r, FALSE);
5288 r = *tofree;
5289 }
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005290 break;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00005291
Bram Moolenaar8c8de832008-06-24 22:58:06 +00005292 case VAR_FLOAT:
Bram Moolenaar835dc632016-02-07 14:27:38 +01005293#ifdef FEAT_FLOAT
Bram Moolenaar8c8de832008-06-24 22:58:06 +00005294 *tofree = NULL;
5295 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
5296 r = numbuf;
5297 break;
5298#endif
5299
Bram Moolenaar520e1e42016-01-23 19:46:28 +01005300 case VAR_SPECIAL:
5301 *tofree = NULL;
Bram Moolenaar17a13432016-01-24 14:22:10 +01005302 r = (char_u *)get_var_special_name(tv->vval.v_number);
Bram Moolenaar520e1e42016-01-23 19:46:28 +01005303 break;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005304 }
Bram Moolenaare9a41262005-01-15 22:18:47 +00005305
Bram Moolenaar8502c702014-06-17 12:51:16 +02005306 if (--recurse == 0)
5307 did_echo_string_emsg = FALSE;
Bram Moolenaare9a41262005-01-15 22:18:47 +00005308 return r;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005309}
5310
5311/*
5312 * Return a string with the string representation of a variable.
5313 * If the memory is allocated "tofree" is set to it, otherwise NULL.
5314 * "numbuf" is used for a number.
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005315 * Does not put quotes around strings, as ":echo" displays values.
5316 * When "copyID" is not NULL replace recursive lists and dicts with "...".
5317 * May return NULL.
5318 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005319 char_u *
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005320echo_string(
5321 typval_T *tv,
5322 char_u **tofree,
5323 char_u *numbuf,
5324 int copyID)
5325{
5326 return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE);
5327}
5328
5329/*
5330 * Return a string with the string representation of a variable.
5331 * If the memory is allocated "tofree" is set to it, otherwise NULL.
5332 * "numbuf" is used for a number.
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005333 * Puts quotes around strings, so that they can be parsed back by eval().
Bram Moolenaar92c5aba2007-08-14 20:29:31 +00005334 * May return NULL.
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005335 */
Bram Moolenaar8110a092016-04-14 15:56:09 +02005336 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01005337tv2string(
5338 typval_T *tv,
5339 char_u **tofree,
5340 char_u *numbuf,
5341 int copyID)
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005342{
Bram Moolenaar18dfb442016-05-31 22:31:23 +02005343 return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00005344}
5345
5346/*
Bram Moolenaar33570922005-01-25 22:26:29 +00005347 * Return string "str" in ' quotes, doubling ' characters.
5348 * If "str" is NULL an empty string is assumed.
Bram Moolenaar8c711452005-01-14 21:53:12 +00005349 * If "function" is TRUE make it function('string').
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005350 */
Bram Moolenaarcd524592016-07-17 14:57:05 +02005351 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01005352string_quote(char_u *str, int function)
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005353{
Bram Moolenaar33570922005-01-25 22:26:29 +00005354 unsigned len;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005355 char_u *p, *r, *s;
5356
Bram Moolenaar33570922005-01-25 22:26:29 +00005357 len = (function ? 13 : 3);
5358 if (str != NULL)
5359 {
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00005360 len += (unsigned)STRLEN(str);
Bram Moolenaar91acfff2017-03-12 19:22:36 +01005361 for (p = str; *p != NUL; MB_PTR_ADV(p))
Bram Moolenaar33570922005-01-25 22:26:29 +00005362 if (*p == '\'')
5363 ++len;
5364 }
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005365 s = r = alloc(len);
5366 if (r != NULL)
5367 {
5368 if (function)
5369 {
Bram Moolenaar8c711452005-01-14 21:53:12 +00005370 STRCPY(r, "function('");
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005371 r += 10;
5372 }
5373 else
Bram Moolenaar8c711452005-01-14 21:53:12 +00005374 *r++ = '\'';
Bram Moolenaar33570922005-01-25 22:26:29 +00005375 if (str != NULL)
5376 for (p = str; *p != NUL; )
5377 {
5378 if (*p == '\'')
5379 *r++ = '\'';
5380 MB_COPY_CHAR(p, r);
5381 }
Bram Moolenaar8c711452005-01-14 21:53:12 +00005382 *r++ = '\'';
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005383 if (function)
5384 *r++ = ')';
5385 *r++ = NUL;
5386 }
5387 return s;
5388}
5389
Bram Moolenaar520e1e42016-01-23 19:46:28 +01005390#if defined(FEAT_FLOAT) || defined(PROTO)
Bram Moolenaar8c8de832008-06-24 22:58:06 +00005391/*
5392 * Convert the string "text" to a floating point number.
5393 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure
5394 * this always uses a decimal point.
5395 * Returns the length of the text that was consumed.
5396 */
Bram Moolenaar520e1e42016-01-23 19:46:28 +01005397 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005398string2float(
5399 char_u *text,
5400 float_T *value) /* result stored here */
Bram Moolenaar8c8de832008-06-24 22:58:06 +00005401{
5402 char *s = (char *)text;
5403 float_T f;
5404
Bram Moolenaar62473612017-01-08 19:25:40 +01005405 /* MS-Windows does not deal with "inf" and "nan" properly. */
5406 if (STRNICMP(text, "inf", 3) == 0)
5407 {
5408 *value = INFINITY;
5409 return 3;
5410 }
5411 if (STRNICMP(text, "-inf", 3) == 0)
5412 {
5413 *value = -INFINITY;
5414 return 4;
5415 }
5416 if (STRNICMP(text, "nan", 3) == 0)
5417 {
5418 *value = NAN;
5419 return 3;
5420 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00005421 f = strtod(s, &s);
5422 *value = f;
5423 return (int)((char_u *)s - text);
5424}
5425#endif
5426
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00005427/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005428 * Get the value of an environment variable.
5429 * "arg" is pointing to the '$'. It is advanced to after the name.
5430 * If the environment variable was not set, silently assume it is empty.
Bram Moolenaare512c8c2014-04-29 17:41:22 +02005431 * Return FAIL if the name is invalid.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005432 */
5433 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005434get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005435{
5436 char_u *string = NULL;
5437 int len;
5438 int cc;
5439 char_u *name;
Bram Moolenaar05159a02005-02-26 23:04:13 +00005440 int mustfree = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005441
5442 ++*arg;
5443 name = *arg;
5444 len = get_env_len(arg);
5445 if (evaluate)
5446 {
Bram Moolenaare512c8c2014-04-29 17:41:22 +02005447 if (len == 0)
Bram Moolenaar615b9972015-01-14 17:15:05 +01005448 return FAIL; /* invalid empty name */
Bram Moolenaar05159a02005-02-26 23:04:13 +00005449
Bram Moolenaare512c8c2014-04-29 17:41:22 +02005450 cc = name[len];
5451 name[len] = NUL;
5452 /* first try vim_getenv(), fast for normal environment vars */
5453 string = vim_getenv(name, &mustfree);
5454 if (string != NULL && *string != NUL)
5455 {
5456 if (!mustfree)
5457 string = vim_strsave(string);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005458 }
Bram Moolenaare512c8c2014-04-29 17:41:22 +02005459 else
5460 {
5461 if (mustfree)
5462 vim_free(string);
5463
5464 /* next try expanding things like $VIM and ${HOME} */
5465 string = expand_env_save(name - 1);
5466 if (string != NULL && *string == '$')
Bram Moolenaard23a8232018-02-10 18:45:26 +01005467 VIM_CLEAR(string);
Bram Moolenaare512c8c2014-04-29 17:41:22 +02005468 }
5469 name[len] = cc;
5470
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005471 rettv->v_type = VAR_STRING;
5472 rettv->vval.v_string = string;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005473 }
5474
5475 return OK;
5476}
5477
Bram Moolenaard6e256c2011-12-14 15:32:50 +01005478
5479
5480/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005481 * Translate a String variable into a position.
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005482 * Returns NULL when there is an error.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005483 */
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02005484 pos_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01005485var2fpos(
5486 typval_T *varp,
5487 int dollar_lnum, /* TRUE when $ is last line */
5488 int *fnum) /* set to fnum for '0, 'A, etc. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00005489{
Bram Moolenaar261bfea2006-03-01 22:12:31 +00005490 char_u *name;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005491 static pos_T pos;
Bram Moolenaar261bfea2006-03-01 22:12:31 +00005492 pos_T *pp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005493
Bram Moolenaara5525202006-03-02 22:52:09 +00005494 /* Argument can be [lnum, col, coladd]. */
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005495 if (varp->v_type == VAR_LIST)
5496 {
5497 list_T *l;
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005498 int len;
Bram Moolenaara5525202006-03-02 22:52:09 +00005499 int error = FALSE;
Bram Moolenaar477933c2007-07-17 14:32:23 +00005500 listitem_T *li;
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005501
5502 l = varp->vval.v_list;
5503 if (l == NULL)
5504 return NULL;
5505
5506 /* Get the line number */
Bram Moolenaara5525202006-03-02 22:52:09 +00005507 pos.lnum = list_find_nr(l, 0L, &error);
5508 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005509 return NULL; /* invalid line number */
5510
5511 /* Get the column number */
Bram Moolenaara5525202006-03-02 22:52:09 +00005512 pos.col = list_find_nr(l, 1L, &error);
5513 if (error)
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005514 return NULL;
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005515 len = (long)STRLEN(ml_get(pos.lnum));
Bram Moolenaar477933c2007-07-17 14:32:23 +00005516
5517 /* We accept "$" for the column number: last column. */
5518 li = list_find(l, 1L);
5519 if (li != NULL && li->li_tv.v_type == VAR_STRING
5520 && li->li_tv.vval.v_string != NULL
5521 && STRCMP(li->li_tv.vval.v_string, "$") == 0)
5522 pos.col = len + 1;
5523
Bram Moolenaara5525202006-03-02 22:52:09 +00005524 /* Accept a position up to the NUL after the line. */
Bram Moolenaar4c3f5362006-04-11 21:38:50 +00005525 if (pos.col == 0 || (int)pos.col > len + 1)
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005526 return NULL; /* invalid column number */
Bram Moolenaara5525202006-03-02 22:52:09 +00005527 --pos.col;
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005528
Bram Moolenaara5525202006-03-02 22:52:09 +00005529 /* Get the virtual offset. Defaults to zero. */
5530 pos.coladd = list_find_nr(l, 2L, &error);
5531 if (error)
5532 pos.coladd = 0;
Bram Moolenaara5525202006-03-02 22:52:09 +00005533
Bram Moolenaar32466aa2006-02-24 23:53:04 +00005534 return &pos;
5535 }
5536
Bram Moolenaard155d7a2018-12-21 16:04:21 +01005537 name = tv_get_string_chk(varp);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00005538 if (name == NULL)
5539 return NULL;
Bram Moolenaar9ecd0232008-06-20 15:31:51 +00005540 if (name[0] == '.') /* cursor */
Bram Moolenaar071d4272004-06-13 20:20:40 +00005541 return &curwin->w_cursor;
Bram Moolenaar9ecd0232008-06-20 15:31:51 +00005542 if (name[0] == 'v' && name[1] == NUL) /* Visual start */
5543 {
5544 if (VIsual_active)
5545 return &VIsual;
5546 return &curwin->w_cursor;
5547 }
Bram Moolenaar9ecd0232008-06-20 15:31:51 +00005548 if (name[0] == '\'') /* mark */
Bram Moolenaar071d4272004-06-13 20:20:40 +00005549 {
Bram Moolenaar9d182dd2013-01-23 15:53:15 +01005550 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005551 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
5552 return NULL;
5553 return pp;
5554 }
Bram Moolenaara5525202006-03-02 22:52:09 +00005555
Bram Moolenaara5525202006-03-02 22:52:09 +00005556 pos.coladd = 0;
Bram Moolenaara5525202006-03-02 22:52:09 +00005557
Bram Moolenaar477933c2007-07-17 14:32:23 +00005558 if (name[0] == 'w' && dollar_lnum)
Bram Moolenaarf52c7252006-02-10 23:23:57 +00005559 {
5560 pos.col = 0;
5561 if (name[1] == '0') /* "w0": first visible line */
5562 {
Bram Moolenaarf740b292006-02-16 22:11:02 +00005563 update_topline();
Bram Moolenaara1d5fa62017-04-03 22:02:55 +02005564 /* In silent Ex mode topline is zero, but that's not a valid line
5565 * number; use one instead. */
5566 pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1;
Bram Moolenaarf52c7252006-02-10 23:23:57 +00005567 return &pos;
5568 }
5569 else if (name[1] == '$') /* "w$": last visible line */
5570 {
Bram Moolenaarf740b292006-02-16 22:11:02 +00005571 validate_botline();
Bram Moolenaara1d5fa62017-04-03 22:02:55 +02005572 /* In silent Ex mode botline is zero, return zero then. */
5573 pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0;
Bram Moolenaarf52c7252006-02-10 23:23:57 +00005574 return &pos;
5575 }
5576 }
5577 else if (name[0] == '$') /* last column or line */
Bram Moolenaar071d4272004-06-13 20:20:40 +00005578 {
Bram Moolenaar477933c2007-07-17 14:32:23 +00005579 if (dollar_lnum)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005580 {
5581 pos.lnum = curbuf->b_ml.ml_line_count;
5582 pos.col = 0;
5583 }
5584 else
5585 {
5586 pos.lnum = curwin->w_cursor.lnum;
5587 pos.col = (colnr_T)STRLEN(ml_get_curline());
5588 }
5589 return &pos;
5590 }
5591 return NULL;
5592}
5593
5594/*
Bram Moolenaar0e34f622006-03-03 23:00:03 +00005595 * Convert list in "arg" into a position and optional file number.
5596 * When "fnump" is NULL there is no file number, only 3 items.
5597 * Note that the column is passed on as-is, the caller may want to decrement
5598 * it to use 1 for the first column.
5599 * Return FAIL when conversion is not possible, doesn't check the position for
5600 * validity.
5601 */
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02005602 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005603list2fpos(
5604 typval_T *arg,
5605 pos_T *posp,
5606 int *fnump,
5607 colnr_T *curswantp)
Bram Moolenaar0e34f622006-03-03 23:00:03 +00005608{
5609 list_T *l = arg->vval.v_list;
5610 long i = 0;
5611 long n;
5612
Bram Moolenaar493c1782014-05-28 14:34:46 +02005613 /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only
5614 * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */
Bram Moolenaarbde35262006-07-23 20:12:24 +00005615 if (arg->v_type != VAR_LIST
5616 || l == NULL
5617 || l->lv_len < (fnump == NULL ? 2 : 3)
Bram Moolenaar493c1782014-05-28 14:34:46 +02005618 || l->lv_len > (fnump == NULL ? 4 : 5))
Bram Moolenaar0e34f622006-03-03 23:00:03 +00005619 return FAIL;
5620
5621 if (fnump != NULL)
5622 {
5623 n = list_find_nr(l, i++, NULL); /* fnum */
5624 if (n < 0)
5625 return FAIL;
5626 if (n == 0)
5627 n = curbuf->b_fnum; /* current buffer */
5628 *fnump = n;
5629 }
5630
5631 n = list_find_nr(l, i++, NULL); /* lnum */
5632 if (n < 0)
5633 return FAIL;
5634 posp->lnum = n;
5635
5636 n = list_find_nr(l, i++, NULL); /* col */
5637 if (n < 0)
5638 return FAIL;
5639 posp->col = n;
5640
Bram Moolenaar493c1782014-05-28 14:34:46 +02005641 n = list_find_nr(l, i, NULL); /* off */
Bram Moolenaar0e34f622006-03-03 23:00:03 +00005642 if (n < 0)
Bram Moolenaarbde35262006-07-23 20:12:24 +00005643 posp->coladd = 0;
5644 else
5645 posp->coladd = n;
Bram Moolenaar0e34f622006-03-03 23:00:03 +00005646
Bram Moolenaar493c1782014-05-28 14:34:46 +02005647 if (curswantp != NULL)
5648 *curswantp = list_find_nr(l, i + 1, NULL); /* curswant */
5649
Bram Moolenaar0e34f622006-03-03 23:00:03 +00005650 return OK;
5651}
5652
5653/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005654 * Get the length of an environment variable name.
5655 * Advance "arg" to the first character after the name.
5656 * Return 0 for error.
5657 */
Bram Moolenaar0522ba02019-08-27 22:48:30 +02005658 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005659get_env_len(char_u **arg)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005660{
5661 char_u *p;
5662 int len;
5663
5664 for (p = *arg; vim_isIDc(*p); ++p)
5665 ;
5666 if (p == *arg) /* no name found */
5667 return 0;
5668
5669 len = (int)(p - *arg);
5670 *arg = p;
5671 return len;
5672}
5673
5674/*
5675 * Get the length of the name of a function or internal variable.
5676 * "arg" is advanced to the first non-white character after the name.
5677 * Return 0 if something is wrong.
5678 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005679 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005680get_id_len(char_u **arg)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005681{
5682 char_u *p;
5683 int len;
5684
5685 /* Find the end of the name. */
5686 for (p = *arg; eval_isnamec(*p); ++p)
Bram Moolenaar9bbf63d2016-01-16 16:49:28 +01005687 {
5688 if (*p == ':')
5689 {
5690 /* "s:" is start of "s:var", but "n:" is not and can be used in
5691 * slice "[n:]". Also "xx:" is not a namespace. */
5692 len = (int)(p - *arg);
5693 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL)
5694 || len > 1)
5695 break;
5696 }
5697 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00005698 if (p == *arg) /* no name found */
5699 return 0;
5700
5701 len = (int)(p - *arg);
5702 *arg = skipwhite(p);
5703
5704 return len;
5705}
5706
5707/*
Bram Moolenaara7043832005-01-21 11:56:39 +00005708 * Get the length of the name of a variable or function.
5709 * Only the name is recognized, does not handle ".key" or "[idx]".
Bram Moolenaar071d4272004-06-13 20:20:40 +00005710 * "arg" is advanced to the first non-white character after the name.
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00005711 * Return -1 if curly braces expansion failed.
5712 * Return 0 if something else is wrong.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005713 * If the name contains 'magic' {}'s, expand them and return the
5714 * expanded name in an allocated string via 'alias' - caller must free.
5715 */
Bram Moolenaar0522ba02019-08-27 22:48:30 +02005716 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005717get_name_len(
5718 char_u **arg,
5719 char_u **alias,
5720 int evaluate,
5721 int verbose)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005722{
5723 int len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005724 char_u *p;
5725 char_u *expr_start;
5726 char_u *expr_end;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005727
5728 *alias = NULL; /* default to no alias */
5729
5730 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
5731 && (*arg)[2] == (int)KE_SNR)
5732 {
5733 /* hard coded <SNR>, already translated */
5734 *arg += 3;
5735 return get_id_len(arg) + 3;
5736 }
5737 len = eval_fname_script(*arg);
5738 if (len > 0)
5739 {
5740 /* literal "<SID>", "s:" or "<SNR>" */
5741 *arg += len;
5742 }
5743
Bram Moolenaar071d4272004-06-13 20:20:40 +00005744 /*
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005745 * Find the end of the name; check for {} construction.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005746 */
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00005747 p = find_name_end(*arg, &expr_start, &expr_end,
5748 len > 0 ? 0 : FNE_CHECK_START);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005749 if (expr_start != NULL)
5750 {
5751 char_u *temp_string;
5752
5753 if (!evaluate)
5754 {
5755 len += (int)(p - *arg);
5756 *arg = skipwhite(p);
5757 return len;
5758 }
5759
5760 /*
5761 * Include any <SID> etc in the expanded string:
5762 * Thus the -len here.
5763 */
5764 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
5765 if (temp_string == NULL)
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00005766 return -1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005767 *alias = temp_string;
5768 *arg = skipwhite(p);
5769 return (int)STRLEN(temp_string);
5770 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00005771
5772 len += get_id_len(arg);
Bram Moolenaar8309b052019-01-13 16:46:22 +01005773 // Only give an error when there is something, otherwise it will be
5774 // reported at a higher level.
5775 if (len == 0 && verbose && **arg != NUL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005776 semsg(_(e_invexpr2), *arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005777
5778 return len;
5779}
5780
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005781/*
5782 * Find the end of a variable or function name, taking care of magic braces.
5783 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the
5784 * start and end of the first magic braces item.
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00005785 * "flags" can have FNE_INCL_BR and FNE_CHECK_START.
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005786 * Return a pointer to just after the name. Equal to "arg" if there is no
5787 * valid name.
5788 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005789 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01005790find_name_end(
5791 char_u *arg,
5792 char_u **expr_start,
5793 char_u **expr_end,
5794 int flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005795{
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005796 int mb_nest = 0;
5797 int br_nest = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005798 char_u *p;
Bram Moolenaar9bbf63d2016-01-16 16:49:28 +01005799 int len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005800
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005801 if (expr_start != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005802 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005803 *expr_start = NULL;
5804 *expr_end = NULL;
5805 }
5806
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00005807 /* Quick check for valid starting character. */
5808 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{')
5809 return arg;
5810
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005811 for (p = arg; *p != NUL
5812 && (eval_isnamec(*p)
Bram Moolenaare9a41262005-01-15 22:18:47 +00005813 || *p == '{'
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00005814 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.'))
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005815 || mb_nest != 0
Bram Moolenaar91acfff2017-03-12 19:22:36 +01005816 || br_nest != 0); MB_PTR_ADV(p))
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005817 {
Bram Moolenaar8af24422005-08-08 22:06:28 +00005818 if (*p == '\'')
5819 {
5820 /* skip over 'string' to avoid counting [ and ] inside it. */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01005821 for (p = p + 1; *p != NUL && *p != '\''; MB_PTR_ADV(p))
Bram Moolenaar8af24422005-08-08 22:06:28 +00005822 ;
5823 if (*p == NUL)
5824 break;
5825 }
5826 else if (*p == '"')
5827 {
5828 /* skip over "str\"ing" to avoid counting [ and ] inside it. */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01005829 for (p = p + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
Bram Moolenaar8af24422005-08-08 22:06:28 +00005830 if (*p == '\\' && p[1] != NUL)
5831 ++p;
5832 if (*p == NUL)
5833 break;
5834 }
Bram Moolenaar9bbf63d2016-01-16 16:49:28 +01005835 else if (br_nest == 0 && mb_nest == 0 && *p == ':')
5836 {
5837 /* "s:" is start of "s:var", but "n:" is not and can be used in
Bram Moolenaar4119cf82016-01-17 14:59:01 +01005838 * slice "[n:]". Also "xx:" is not a namespace. But {ns}: is. */
Bram Moolenaar9bbf63d2016-01-16 16:49:28 +01005839 len = (int)(p - arg);
5840 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL)
Bram Moolenaar4119cf82016-01-17 14:59:01 +01005841 || (len > 1 && p[-1] != '}'))
Bram Moolenaar9bbf63d2016-01-16 16:49:28 +01005842 break;
5843 }
Bram Moolenaar8af24422005-08-08 22:06:28 +00005844
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005845 if (mb_nest == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005846 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005847 if (*p == '[')
5848 ++br_nest;
5849 else if (*p == ']')
5850 --br_nest;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005851 }
Bram Moolenaar8af24422005-08-08 22:06:28 +00005852
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005853 if (br_nest == 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005854 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00005855 if (*p == '{')
5856 {
5857 mb_nest++;
5858 if (expr_start != NULL && *expr_start == NULL)
5859 *expr_start = p;
5860 }
5861 else if (*p == '}')
5862 {
5863 mb_nest--;
5864 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL)
5865 *expr_end = p;
5866 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00005867 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00005868 }
5869
5870 return p;
5871}
5872
5873/*
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00005874 * Expands out the 'magic' {}'s in a variable/function name.
5875 * Note that this can call itself recursively, to deal with
5876 * constructs like foo{bar}{baz}{bam}
5877 * The four pointer arguments point to "foo{expre}ss{ion}bar"
5878 * "in_start" ^
5879 * "expr_start" ^
5880 * "expr_end" ^
5881 * "in_end" ^
5882 *
5883 * Returns a new allocated string, which the caller must free.
5884 * Returns NULL for failure.
5885 */
5886 static char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01005887make_expanded_name(
5888 char_u *in_start,
5889 char_u *expr_start,
5890 char_u *expr_end,
5891 char_u *in_end)
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00005892{
5893 char_u c1;
5894 char_u *retval = NULL;
5895 char_u *temp_result;
5896 char_u *nextcmd = NULL;
5897
5898 if (expr_end == NULL || in_end == NULL)
5899 return NULL;
5900 *expr_start = NUL;
5901 *expr_end = NUL;
5902 c1 = *in_end;
5903 *in_end = NUL;
5904
Bram Moolenaar362e1a32006-03-06 23:29:24 +00005905 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00005906 if (temp_result != NULL && nextcmd == NULL)
5907 {
Bram Moolenaar964b3742019-05-24 18:54:09 +02005908 retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
5909 + (in_end - expr_end) + 1);
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00005910 if (retval != NULL)
5911 {
5912 STRCPY(retval, in_start);
5913 STRCAT(retval, temp_result);
5914 STRCAT(retval, expr_end + 1);
5915 }
5916 }
5917 vim_free(temp_result);
5918
5919 *in_end = c1; /* put char back for error messages */
5920 *expr_start = '{';
5921 *expr_end = '}';
5922
5923 if (retval != NULL)
5924 {
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00005925 temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00005926 if (expr_start != NULL)
5927 {
5928 /* Further expansion! */
5929 temp_result = make_expanded_name(retval, expr_start,
5930 expr_end, temp_result);
5931 vim_free(retval);
5932 retval = temp_result;
5933 }
5934 }
5935
5936 return retval;
5937}
5938
5939/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005940 * Return TRUE if character "c" can be used in a variable or function name.
Bram Moolenaare9a41262005-01-15 22:18:47 +00005941 * Does not include '{' or '}' for magic braces.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005942 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005943 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005944eval_isnamec(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005945{
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00005946 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR);
5947}
5948
5949/*
5950 * Return TRUE if character "c" can be used as the first character in a
5951 * variable or function name (excluding '{' and '}').
5952 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02005953 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01005954eval_isnamec1(int c)
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00005955{
5956 return (ASCII_ISALPHA(c) || c == '_');
Bram Moolenaar071d4272004-06-13 20:20:40 +00005957}
5958
5959/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005960 * Set number v: variable to "val".
5961 */
5962 void
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02005963set_vim_var_nr(int idx, varnumber_T val)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005964{
Bram Moolenaare9a41262005-01-15 22:18:47 +00005965 vimvars[idx].vv_nr = val;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005966}
5967
5968/*
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02005969 * Get typval_T v: variable value.
5970 */
5971 typval_T *
5972get_vim_var_tv(int idx)
5973{
5974 return &vimvars[idx].vv_tv;
5975}
5976
5977/*
Bram Moolenaar19a09a12005-03-04 23:39:37 +00005978 * Get number v: variable value.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005979 */
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02005980 varnumber_T
Bram Moolenaar7454a062016-01-30 15:14:10 +01005981get_vim_var_nr(int idx)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005982{
Bram Moolenaare9a41262005-01-15 22:18:47 +00005983 return vimvars[idx].vv_nr;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005984}
5985
Bram Moolenaar19a09a12005-03-04 23:39:37 +00005986/*
5987 * Get string v: variable value. Uses a static buffer, can only be used once.
Bram Moolenaar6e65d592017-12-07 22:11:27 +01005988 * If the String variable has never been set, return an empty string.
5989 * Never returns NULL;
Bram Moolenaar19a09a12005-03-04 23:39:37 +00005990 */
5991 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01005992get_vim_var_str(int idx)
Bram Moolenaar19a09a12005-03-04 23:39:37 +00005993{
Bram Moolenaard155d7a2018-12-21 16:04:21 +01005994 return tv_get_string(&vimvars[idx].vv_tv);
Bram Moolenaar19a09a12005-03-04 23:39:37 +00005995}
Bram Moolenaar19a09a12005-03-04 23:39:37 +00005996
Bram Moolenaar071d4272004-06-13 20:20:40 +00005997/*
Bram Moolenaard812df62008-11-09 12:46:09 +00005998 * Get List v: variable value. Caller must take care of reference count when
5999 * needed.
6000 */
6001 list_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006002get_vim_var_list(int idx)
Bram Moolenaard812df62008-11-09 12:46:09 +00006003{
6004 return vimvars[idx].vv_list;
6005}
6006
6007/*
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01006008 * Get Dict v: variable value. Caller must take care of reference count when
6009 * needed.
6010 */
6011 dict_T *
6012get_vim_var_dict(int idx)
6013{
6014 return vimvars[idx].vv_dict;
6015}
6016
6017/*
Bram Moolenaarda9591e2009-09-30 13:17:02 +00006018 * Set v:char to character "c".
6019 */
6020 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006021set_vim_var_char(int c)
Bram Moolenaarda9591e2009-09-30 13:17:02 +00006022{
Bram Moolenaar9a920d82012-06-01 15:21:02 +02006023 char_u buf[MB_MAXBYTES + 1];
Bram Moolenaarda9591e2009-09-30 13:17:02 +00006024
Bram Moolenaarda9591e2009-09-30 13:17:02 +00006025 if (has_mbyte)
6026 buf[(*mb_char2bytes)(c, buf)] = NUL;
6027 else
Bram Moolenaarda9591e2009-09-30 13:17:02 +00006028 {
6029 buf[0] = c;
6030 buf[1] = NUL;
6031 }
6032 set_vim_var_string(VV_CHAR, buf, -1);
6033}
6034
6035/*
Bram Moolenaar8df74be2008-11-20 15:12:02 +00006036 * Set v:count to "count" and v:count1 to "count1".
6037 * When "set_prevcount" is TRUE first set v:prevcount from v:count.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006038 */
6039 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006040set_vcount(
6041 long count,
6042 long count1,
6043 int set_prevcount)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006044{
Bram Moolenaar8df74be2008-11-20 15:12:02 +00006045 if (set_prevcount)
6046 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
Bram Moolenaare9a41262005-01-15 22:18:47 +00006047 vimvars[VV_COUNT].vv_nr = count;
6048 vimvars[VV_COUNT1].vv_nr = count1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006049}
6050
6051/*
Bram Moolenaarb0f42ba2018-05-12 15:38:26 +02006052 * Save variables that might be changed as a side effect. Used when executing
6053 * a timer callback.
6054 */
6055 void
6056save_vimvars(vimvars_save_T *vvsave)
6057{
6058 vvsave->vv_prevcount = vimvars[VV_PREVCOUNT].vv_nr;
6059 vvsave->vv_count = vimvars[VV_COUNT].vv_nr;
6060 vvsave->vv_count1 = vimvars[VV_COUNT1].vv_nr;
6061}
6062
6063/*
6064 * Restore variables saved by save_vimvars().
6065 */
6066 void
6067restore_vimvars(vimvars_save_T *vvsave)
6068{
6069 vimvars[VV_PREVCOUNT].vv_nr = vvsave->vv_prevcount;
6070 vimvars[VV_COUNT].vv_nr = vvsave->vv_count;
6071 vimvars[VV_COUNT1].vv_nr = vvsave->vv_count1;
6072}
6073
6074/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006075 * Set string v: variable to a copy of "val".
6076 */
6077 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006078set_vim_var_string(
6079 int idx,
6080 char_u *val,
6081 int len) /* length of "val" to use or -1 (whole string) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006082{
Bram Moolenaara542c682016-01-31 16:28:04 +01006083 clear_tv(&vimvars[idx].vv_di.di_tv);
6084 vimvars[idx].vv_type = VAR_STRING;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006085 if (val == NULL)
Bram Moolenaare9a41262005-01-15 22:18:47 +00006086 vimvars[idx].vv_str = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006087 else if (len == -1)
Bram Moolenaare9a41262005-01-15 22:18:47 +00006088 vimvars[idx].vv_str = vim_strsave(val);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006089 else
Bram Moolenaare9a41262005-01-15 22:18:47 +00006090 vimvars[idx].vv_str = vim_strnsave(val, len);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006091}
6092
6093/*
Bram Moolenaard812df62008-11-09 12:46:09 +00006094 * Set List v: variable to "val".
6095 */
6096 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006097set_vim_var_list(int idx, list_T *val)
Bram Moolenaard812df62008-11-09 12:46:09 +00006098{
Bram Moolenaara542c682016-01-31 16:28:04 +01006099 clear_tv(&vimvars[idx].vv_di.di_tv);
6100 vimvars[idx].vv_type = VAR_LIST;
Bram Moolenaard812df62008-11-09 12:46:09 +00006101 vimvars[idx].vv_list = val;
6102 if (val != NULL)
6103 ++val->lv_refcount;
6104}
6105
6106/*
Bram Moolenaar42a45122015-07-10 17:56:23 +02006107 * Set Dictionary v: variable to "val".
6108 */
6109 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006110set_vim_var_dict(int idx, dict_T *val)
Bram Moolenaar42a45122015-07-10 17:56:23 +02006111{
Bram Moolenaara542c682016-01-31 16:28:04 +01006112 clear_tv(&vimvars[idx].vv_di.di_tv);
6113 vimvars[idx].vv_type = VAR_DICT;
Bram Moolenaar42a45122015-07-10 17:56:23 +02006114 vimvars[idx].vv_dict = val;
6115 if (val != NULL)
6116 {
6117 ++val->dv_refcount;
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01006118 dict_set_items_ro(val);
Bram Moolenaar42a45122015-07-10 17:56:23 +02006119 }
6120}
6121
6122/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006123 * Set v:register if needed.
6124 */
6125 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006126set_reg_var(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006127{
6128 char_u regname;
6129
6130 if (c == 0 || c == ' ')
6131 regname = '"';
6132 else
6133 regname = c;
6134 /* Avoid free/alloc when the value is already right. */
Bram Moolenaare9a41262005-01-15 22:18:47 +00006135 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006136 set_vim_var_string(VV_REG, &regname, 1);
6137}
6138
6139/*
6140 * Get or set v:exception. If "oldval" == NULL, return the current value.
6141 * Otherwise, restore the value to "oldval" and return NULL.
6142 * Must always be called in pairs to save and restore v:exception! Does not
6143 * take care of memory allocations.
6144 */
6145 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006146v_exception(char_u *oldval)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006147{
6148 if (oldval == NULL)
Bram Moolenaare9a41262005-01-15 22:18:47 +00006149 return vimvars[VV_EXCEPTION].vv_str;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006150
Bram Moolenaare9a41262005-01-15 22:18:47 +00006151 vimvars[VV_EXCEPTION].vv_str = oldval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006152 return NULL;
6153}
6154
6155/*
6156 * Get or set v:throwpoint. If "oldval" == NULL, return the current value.
6157 * Otherwise, restore the value to "oldval" and return NULL.
6158 * Must always be called in pairs to save and restore v:throwpoint! Does not
6159 * take care of memory allocations.
6160 */
6161 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006162v_throwpoint(char_u *oldval)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006163{
6164 if (oldval == NULL)
Bram Moolenaare9a41262005-01-15 22:18:47 +00006165 return vimvars[VV_THROWPOINT].vv_str;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006166
Bram Moolenaare9a41262005-01-15 22:18:47 +00006167 vimvars[VV_THROWPOINT].vv_str = oldval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006168 return NULL;
6169}
6170
Bram Moolenaar071d4272004-06-13 20:20:40 +00006171/*
6172 * Set v:cmdarg.
6173 * If "eap" != NULL, use "eap" to generate the value and return the old value.
6174 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
6175 * Must always be called in pairs!
6176 */
6177 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006178set_cmdarg(exarg_T *eap, char_u *oldarg)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006179{
6180 char_u *oldval;
6181 char_u *newval;
6182 unsigned len;
6183
Bram Moolenaare9a41262005-01-15 22:18:47 +00006184 oldval = vimvars[VV_CMDARG].vv_str;
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006185 if (eap == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006186 {
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006187 vim_free(oldval);
Bram Moolenaare9a41262005-01-15 22:18:47 +00006188 vimvars[VV_CMDARG].vv_str = oldarg;
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006189 return NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006190 }
6191
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006192 if (eap->force_bin == FORCE_BIN)
6193 len = 6;
6194 else if (eap->force_bin == FORCE_NOBIN)
6195 len = 8;
6196 else
6197 len = 0;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006198
6199 if (eap->read_edit)
6200 len += 7;
6201
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006202 if (eap->force_ff != 0)
Bram Moolenaar333b80a2018-04-04 22:57:29 +02006203 len += 10; /* " ++ff=unix" */
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006204 if (eap->force_enc != 0)
6205 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
Bram Moolenaar34b4daf2010-05-16 13:26:25 +02006206 if (eap->bad_char != 0)
6207 len += 7 + 4; /* " ++bad=" + "keep" or "drop" */
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006208
6209 newval = alloc(len + 1);
6210 if (newval == NULL)
6211 return NULL;
6212
6213 if (eap->force_bin == FORCE_BIN)
6214 sprintf((char *)newval, " ++bin");
6215 else if (eap->force_bin == FORCE_NOBIN)
6216 sprintf((char *)newval, " ++nobin");
6217 else
6218 *newval = NUL;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006219
6220 if (eap->read_edit)
6221 STRCAT(newval, " ++edit");
6222
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006223 if (eap->force_ff != 0)
6224 sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
Bram Moolenaar333b80a2018-04-04 22:57:29 +02006225 eap->force_ff == 'u' ? "unix"
6226 : eap->force_ff == 'd' ? "dos"
6227 : "mac");
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006228 if (eap->force_enc != 0)
6229 sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
6230 eap->cmd + eap->force_enc);
Bram Moolenaar34b4daf2010-05-16 13:26:25 +02006231 if (eap->bad_char == BAD_KEEP)
6232 STRCPY(newval + STRLEN(newval), " ++bad=keep");
6233 else if (eap->bad_char == BAD_DROP)
6234 STRCPY(newval + STRLEN(newval), " ++bad=drop");
6235 else if (eap->bad_char != 0)
6236 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char);
Bram Moolenaare9a41262005-01-15 22:18:47 +00006237 vimvars[VV_CMDARG].vv_str = newval;
Bram Moolenaar3fdfa4a2004-10-07 21:02:47 +00006238 return oldval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006239}
Bram Moolenaar071d4272004-06-13 20:20:40 +00006240
6241/*
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006242 * Check if variable "name[len]" is a local variable or an argument.
6243 * If so, "*eval_lavars_used" is set to TRUE.
6244 */
6245 static void
6246check_vars(char_u *name, int len)
6247{
6248 int cc;
6249 char_u *varname;
6250 hashtab_T *ht;
6251
6252 if (eval_lavars_used == NULL)
6253 return;
6254
6255 /* truncate the name, so that we can use strcmp() */
6256 cc = name[len];
6257 name[len] = NUL;
6258
6259 ht = find_var_ht(name, &varname);
6260 if (ht == get_funccal_local_ht() || ht == get_funccal_args_ht())
6261 {
6262 if (find_var(name, NULL, TRUE) != NULL)
6263 *eval_lavars_used = TRUE;
6264 }
6265
6266 name[len] = cc;
6267}
6268
6269/*
Bram Moolenaarac92e252019-08-03 21:58:38 +02006270 * Handle:
6271 * - expr[expr], expr[expr:expr] subscript
6272 * - ".name" lookup
6273 * - function call with Funcref variable: func(expr)
6274 * - method call: var->method()
6275 *
6276 * Can all be combined in any order: dict.func(expr)[idx]['func'](expr)->len()
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006277 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006278 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01006279handle_subscript(
6280 char_u **arg,
6281 typval_T *rettv,
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02006282 int evaluate, // do more than finding the end
6283 int verbose, // give error messages
6284 char_u *start_leader, // start of '!' and '-' prefixes
6285 char_u **end_leaderp) // end of '!' and '-' prefixes
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006286{
6287 int ret = OK;
6288 dict_T *selfdict = NULL;
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006289
Bram Moolenaar61343f02019-07-20 21:11:13 +02006290 // "." is ".name" lookup when we found a dict or when evaluating and
6291 // scriptversion is at least 2, where string concatenation is "..".
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006292 while (ret == OK
Bram Moolenaarac92e252019-08-03 21:58:38 +02006293 && (((**arg == '['
6294 || (**arg == '.' && (rettv->v_type == VAR_DICT
Bram Moolenaar61343f02019-07-20 21:11:13 +02006295 || (!evaluate
6296 && (*arg)[1] != '.'
6297 && current_sctx.sc_version >= 2)))
Bram Moolenaarac92e252019-08-03 21:58:38 +02006298 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
Bram Moolenaar1735bc92016-03-14 23:05:14 +01006299 || rettv->v_type == VAR_PARTIAL)))
Bram Moolenaarac92e252019-08-03 21:58:38 +02006300 && !VIM_ISWHITE(*(*arg - 1)))
6301 || (**arg == '-' && (*arg)[1] == '>')))
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006302 {
6303 if (**arg == '(')
6304 {
Bram Moolenaar22a0c0c2019-08-09 23:25:08 +02006305 ret = call_func_rettv(arg, rettv, evaluate, selfdict, NULL);
Bram Moolenaar3f242a82016-03-18 19:39:25 +01006306
Bram Moolenaar22a0c0c2019-08-09 23:25:08 +02006307 // Stop the expression evaluation when immediately aborting on
6308 // error, or when an interrupt occurred or an exception was thrown
6309 // but not caught.
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006310 if (aborting())
6311 {
6312 if (ret == OK)
6313 clear_tv(rettv);
6314 ret = FAIL;
6315 }
6316 dict_unref(selfdict);
6317 selfdict = NULL;
6318 }
Bram Moolenaarac92e252019-08-03 21:58:38 +02006319 else if (**arg == '-')
6320 {
Bram Moolenaar9cfe8f62019-08-17 21:04:16 +02006321 // Expression "-1.0->method()" applies the leader "-" before
6322 // applying ->.
6323 if (evaluate && *end_leaderp > start_leader)
6324 ret = eval7_leader(rettv, start_leader, end_leaderp);
6325 if (ret == OK)
6326 {
6327 if ((*arg)[2] == '{')
6328 // expr->{lambda}()
6329 ret = eval_lambda(arg, rettv, evaluate, verbose);
6330 else
6331 // expr->name()
6332 ret = eval_method(arg, rettv, evaluate, verbose);
6333 }
Bram Moolenaarac92e252019-08-03 21:58:38 +02006334 }
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006335 else /* **arg == '[' || **arg == '.' */
6336 {
6337 dict_unref(selfdict);
6338 if (rettv->v_type == VAR_DICT)
6339 {
6340 selfdict = rettv->vval.v_dict;
6341 if (selfdict != NULL)
6342 ++selfdict->dv_refcount;
6343 }
6344 else
6345 selfdict = NULL;
6346 if (eval_index(arg, rettv, evaluate, verbose) == FAIL)
6347 {
6348 clear_tv(rettv);
6349 ret = FAIL;
6350 }
6351 }
6352 }
Bram Moolenaarab1fa392016-03-15 19:33:34 +01006353
Bram Moolenaar1d429612016-05-24 15:44:17 +02006354 /* Turn "dict.Func" into a partial for "Func" bound to "dict".
6355 * Don't do this when "Func" is already a partial that was bound
6356 * explicitly (pt_auto is FALSE). */
6357 if (selfdict != NULL
6358 && (rettv->v_type == VAR_FUNC
6359 || (rettv->v_type == VAR_PARTIAL
6360 && (rettv->vval.v_partial->pt_auto
6361 || rettv->vval.v_partial->pt_dict == NULL))))
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006362 selfdict = make_partial(selfdict, rettv);
Bram Moolenaarab1fa392016-03-15 19:33:34 +01006363
Bram Moolenaar2a8d1f82005-02-05 21:43:56 +00006364 dict_unref(selfdict);
6365 return ret;
6366}
6367
6368/*
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006369 * Allocate memory for a variable type-value, and make it empty (0 or NULL
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006370 * value).
6371 */
Bram Moolenaar11e0afa2016-02-01 22:41:00 +01006372 typval_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006373alloc_tv(void)
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006374{
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006375 return ALLOC_CLEAR_ONE(typval_T);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006376}
6377
6378/*
6379 * Allocate memory for a variable type-value, and assign a string to it.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006380 * The string "s" must have been allocated, it is consumed.
6381 * Return NULL for out of memory, the variable otherwise.
6382 */
Bram Moolenaar33570922005-01-25 22:26:29 +00006383 static typval_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006384alloc_string_tv(char_u *s)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006385{
Bram Moolenaar33570922005-01-25 22:26:29 +00006386 typval_T *rettv;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006387
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006388 rettv = alloc_tv();
6389 if (rettv != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006390 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006391 rettv->v_type = VAR_STRING;
6392 rettv->vval.v_string = s;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006393 }
6394 else
6395 vim_free(s);
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006396 return rettv;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006397}
6398
6399/*
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006400 * Free the memory for a variable type-value.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006401 */
Bram Moolenaar4770d092006-01-12 23:22:24 +00006402 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006403free_tv(typval_T *varp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006404{
6405 if (varp != NULL)
6406 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006407 switch (varp->v_type)
6408 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006409 case VAR_FUNC:
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00006410 func_unref(varp->vval.v_string);
Bram Moolenaar2f40d122017-10-24 21:49:36 +02006411 /* FALLTHROUGH */
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00006412 case VAR_STRING:
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006413 vim_free(varp->vval.v_string);
6414 break;
Bram Moolenaar1735bc92016-03-14 23:05:14 +01006415 case VAR_PARTIAL:
6416 partial_unref(varp->vval.v_partial);
6417 break;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006418 case VAR_BLOB:
6419 blob_unref(varp->vval.v_blob);
6420 break;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006421 case VAR_LIST:
6422 list_unref(varp->vval.v_list);
6423 break;
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00006424 case VAR_DICT:
6425 dict_unref(varp->vval.v_dict);
6426 break;
Bram Moolenaar835dc632016-02-07 14:27:38 +01006427 case VAR_JOB:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006428#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar835dc632016-02-07 14:27:38 +01006429 job_unref(varp->vval.v_job);
6430 break;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006431#endif
Bram Moolenaar77073442016-02-13 23:23:53 +01006432 case VAR_CHANNEL:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006433#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar77073442016-02-13 23:23:53 +01006434 channel_unref(varp->vval.v_channel);
6435 break;
6436#endif
Bram Moolenaar835dc632016-02-07 14:27:38 +01006437 case VAR_NUMBER:
6438 case VAR_FLOAT:
Bram Moolenaar758711c2005-02-02 23:11:38 +00006439 case VAR_UNKNOWN:
Bram Moolenaar6650a692016-01-26 19:59:10 +01006440 case VAR_SPECIAL:
Bram Moolenaar758711c2005-02-02 23:11:38 +00006441 break;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006442 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00006443 vim_free(varp);
6444 }
6445}
6446
6447/*
6448 * Free the memory for a variable value and set the value to NULL or 0.
6449 */
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00006450 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006451clear_tv(typval_T *varp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006452{
6453 if (varp != NULL)
6454 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006455 switch (varp->v_type)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006456 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006457 case VAR_FUNC:
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00006458 func_unref(varp->vval.v_string);
Bram Moolenaar2f40d122017-10-24 21:49:36 +02006459 /* FALLTHROUGH */
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00006460 case VAR_STRING:
Bram Moolenaard23a8232018-02-10 18:45:26 +01006461 VIM_CLEAR(varp->vval.v_string);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006462 break;
Bram Moolenaar1735bc92016-03-14 23:05:14 +01006463 case VAR_PARTIAL:
6464 partial_unref(varp->vval.v_partial);
6465 varp->vval.v_partial = NULL;
6466 break;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006467 case VAR_BLOB:
6468 blob_unref(varp->vval.v_blob);
6469 varp->vval.v_blob = NULL;
6470 break;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006471 case VAR_LIST:
6472 list_unref(varp->vval.v_list);
Bram Moolenaarce5e58e2005-01-19 22:24:34 +00006473 varp->vval.v_list = NULL;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006474 break;
Bram Moolenaar8c711452005-01-14 21:53:12 +00006475 case VAR_DICT:
6476 dict_unref(varp->vval.v_dict);
Bram Moolenaarce5e58e2005-01-19 22:24:34 +00006477 varp->vval.v_dict = NULL;
Bram Moolenaar8c711452005-01-14 21:53:12 +00006478 break;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006479 case VAR_NUMBER:
Bram Moolenaar520e1e42016-01-23 19:46:28 +01006480 case VAR_SPECIAL:
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006481 varp->vval.v_number = 0;
6482 break;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006483 case VAR_FLOAT:
Bram Moolenaar835dc632016-02-07 14:27:38 +01006484#ifdef FEAT_FLOAT
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006485 varp->vval.v_float = 0.0;
6486 break;
6487#endif
Bram Moolenaar835dc632016-02-07 14:27:38 +01006488 case VAR_JOB:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006489#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar835dc632016-02-07 14:27:38 +01006490 job_unref(varp->vval.v_job);
6491 varp->vval.v_job = NULL;
6492#endif
6493 break;
Bram Moolenaar77073442016-02-13 23:23:53 +01006494 case VAR_CHANNEL:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006495#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar77073442016-02-13 23:23:53 +01006496 channel_unref(varp->vval.v_channel);
6497 varp->vval.v_channel = NULL;
6498#endif
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006499 case VAR_UNKNOWN:
6500 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006501 }
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00006502 varp->v_lock = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006503 }
6504}
6505
6506/*
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006507 * Set the value of a variable to NULL without freeing items.
6508 */
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02006509 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006510init_tv(typval_T *varp)
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006511{
6512 if (varp != NULL)
Bram Moolenaar33570922005-01-25 22:26:29 +00006513 vim_memset(varp, 0, sizeof(typval_T));
Bram Moolenaarc70646c2005-01-04 21:52:38 +00006514}
6515
6516/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006517 * Get the number value of a variable.
6518 * If it is a String variable, uses vim_str2nr().
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006519 * For incompatible types, return 0.
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006520 * tv_get_number_chk() is similar to tv_get_number(), but informs the
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006521 * caller of incompatible types: it sets *denote to TRUE if "denote"
6522 * is not NULL or returns -1 otherwise.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006523 */
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006524 varnumber_T
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006525tv_get_number(typval_T *varp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006526{
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006527 int error = FALSE;
6528
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006529 return tv_get_number_chk(varp, &error); /* return 0L on error */
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006530}
6531
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006532 varnumber_T
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006533tv_get_number_chk(typval_T *varp, int *denote)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006534{
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006535 varnumber_T n = 0L;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006536
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006537 switch (varp->v_type)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006538 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006539 case VAR_NUMBER:
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006540 return varp->vval.v_number;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006541 case VAR_FLOAT:
Bram Moolenaar835dc632016-02-07 14:27:38 +01006542#ifdef FEAT_FLOAT
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006543 emsg(_("E805: Using a Float as a Number"));
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006544 break;
6545#endif
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006546 case VAR_FUNC:
Bram Moolenaar1735bc92016-03-14 23:05:14 +01006547 case VAR_PARTIAL:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006548 emsg(_("E703: Using a Funcref as a Number"));
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006549 break;
6550 case VAR_STRING:
6551 if (varp->vval.v_string != NULL)
6552 vim_str2nr(varp->vval.v_string, NULL, NULL,
Bram Moolenaar16e9b852019-05-19 19:59:35 +02006553 STR2NR_ALL, &n, NULL, 0, FALSE);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006554 return n;
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00006555 case VAR_LIST:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006556 emsg(_("E745: Using a List as a Number"));
Bram Moolenaar31c67ef2005-01-11 21:34:41 +00006557 break;
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00006558 case VAR_DICT:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006559 emsg(_("E728: Using a Dictionary as a Number"));
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00006560 break;
Bram Moolenaar17a13432016-01-24 14:22:10 +01006561 case VAR_SPECIAL:
6562 return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
6563 break;
Bram Moolenaar835dc632016-02-07 14:27:38 +01006564 case VAR_JOB:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006565#ifdef FEAT_JOB_CHANNEL
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006566 emsg(_("E910: Using a Job as a Number"));
Bram Moolenaar835dc632016-02-07 14:27:38 +01006567 break;
6568#endif
Bram Moolenaar77073442016-02-13 23:23:53 +01006569 case VAR_CHANNEL:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006570#ifdef FEAT_JOB_CHANNEL
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006571 emsg(_("E913: Using a Channel as a Number"));
Bram Moolenaar77073442016-02-13 23:23:53 +01006572 break;
6573#endif
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006574 case VAR_BLOB:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006575 emsg(_("E974: Using a Blob as a Number"));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006576 break;
Bram Moolenaara03f2332016-02-06 18:09:59 +01006577 case VAR_UNKNOWN:
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006578 internal_error("tv_get_number(UNKNOWN)");
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006579 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006580 }
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006581 if (denote == NULL) /* useful for values that must be unsigned */
6582 n = -1;
6583 else
6584 *denote = TRUE;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006585 return n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006586}
6587
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006588#ifdef FEAT_FLOAT
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02006589 float_T
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006590tv_get_float(typval_T *varp)
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006591{
6592 switch (varp->v_type)
6593 {
6594 case VAR_NUMBER:
6595 return (float_T)(varp->vval.v_number);
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006596 case VAR_FLOAT:
6597 return varp->vval.v_float;
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006598 case VAR_FUNC:
Bram Moolenaar1735bc92016-03-14 23:05:14 +01006599 case VAR_PARTIAL:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006600 emsg(_("E891: Using a Funcref as a Float"));
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006601 break;
6602 case VAR_STRING:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006603 emsg(_("E892: Using a String as a Float"));
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006604 break;
6605 case VAR_LIST:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006606 emsg(_("E893: Using a List as a Float"));
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006607 break;
6608 case VAR_DICT:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006609 emsg(_("E894: Using a Dictionary as a Float"));
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006610 break;
Bram Moolenaara03f2332016-02-06 18:09:59 +01006611 case VAR_SPECIAL:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006612 emsg(_("E907: Using a special value as a Float"));
Bram Moolenaara03f2332016-02-06 18:09:59 +01006613 break;
Bram Moolenaar835dc632016-02-07 14:27:38 +01006614 case VAR_JOB:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006615# ifdef FEAT_JOB_CHANNEL
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006616 emsg(_("E911: Using a Job as a Float"));
Bram Moolenaar835dc632016-02-07 14:27:38 +01006617 break;
6618# endif
Bram Moolenaar77073442016-02-13 23:23:53 +01006619 case VAR_CHANNEL:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006620# ifdef FEAT_JOB_CHANNEL
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006621 emsg(_("E914: Using a Channel as a Float"));
Bram Moolenaar77073442016-02-13 23:23:53 +01006622 break;
6623# endif
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006624 case VAR_BLOB:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006625 emsg(_("E975: Using a Blob as a Float"));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006626 break;
Bram Moolenaara03f2332016-02-06 18:09:59 +01006627 case VAR_UNKNOWN:
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006628 internal_error("tv_get_float(UNKNOWN)");
Bram Moolenaarf7edf402016-01-19 23:36:15 +01006629 break;
6630 }
6631 return 0;
6632}
6633#endif
6634
Bram Moolenaar071d4272004-06-13 20:20:40 +00006635/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006636 * Get the string value of a variable.
6637 * If it is a Number variable, the number is converted into a string.
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006638 * tv_get_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
6639 * tv_get_string_buf() uses a given buffer.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006640 * If the String variable has never been set, return an empty string.
6641 * Never returns NULL;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006642 * tv_get_string_chk() and tv_get_string_buf_chk() are similar, but return
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006643 * NULL on error.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006644 */
Bram Moolenaar8e2c9422016-03-12 13:43:33 +01006645 char_u *
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006646tv_get_string(typval_T *varp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006647{
6648 static char_u mybuf[NUMBUFLEN];
6649
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006650 return tv_get_string_buf(varp, mybuf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006651}
6652
Bram Moolenaar8e2c9422016-03-12 13:43:33 +01006653 char_u *
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006654tv_get_string_buf(typval_T *varp, char_u *buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006655{
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006656 char_u *res = tv_get_string_buf_chk(varp, buf);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006657
6658 return res != NULL ? res : (char_u *)"";
6659}
6660
Bram Moolenaar7d647822014-04-05 21:28:56 +02006661/*
6662 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
6663 */
Bram Moolenaar4be06f92005-07-29 22:36:03 +00006664 char_u *
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006665tv_get_string_chk(typval_T *varp)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006666{
6667 static char_u mybuf[NUMBUFLEN];
6668
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006669 return tv_get_string_buf_chk(varp, mybuf);
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006670}
6671
Bram Moolenaar520e1e42016-01-23 19:46:28 +01006672 char_u *
Bram Moolenaard155d7a2018-12-21 16:04:21 +01006673tv_get_string_buf_chk(typval_T *varp, char_u *buf)
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006674{
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006675 switch (varp->v_type)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006676 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006677 case VAR_NUMBER:
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006678 vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
Bram Moolenaar88c86eb2019-01-17 17:13:30 +01006679 (long_long_T)varp->vval.v_number);
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006680 return buf;
6681 case VAR_FUNC:
Bram Moolenaar1735bc92016-03-14 23:05:14 +01006682 case VAR_PARTIAL:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006683 emsg(_("E729: using Funcref as a String"));
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006684 break;
6685 case VAR_LIST:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006686 emsg(_("E730: using List as a String"));
Bram Moolenaar8c711452005-01-14 21:53:12 +00006687 break;
6688 case VAR_DICT:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006689 emsg(_("E731: using Dictionary as a String"));
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006690 break;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006691 case VAR_FLOAT:
Bram Moolenaar835dc632016-02-07 14:27:38 +01006692#ifdef FEAT_FLOAT
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006693 emsg(_(e_float_as_string));
Bram Moolenaar8c8de832008-06-24 22:58:06 +00006694 break;
6695#endif
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006696 case VAR_STRING:
6697 if (varp->vval.v_string != NULL)
6698 return varp->vval.v_string;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006699 return (char_u *)"";
Bram Moolenaar17a13432016-01-24 14:22:10 +01006700 case VAR_SPECIAL:
6701 STRCPY(buf, get_var_special_name(varp->vval.v_number));
6702 return buf;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006703 case VAR_BLOB:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006704 emsg(_("E976: using Blob as a String"));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006705 break;
Bram Moolenaar835dc632016-02-07 14:27:38 +01006706 case VAR_JOB:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006707#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar835dc632016-02-07 14:27:38 +01006708 {
6709 job_T *job = varp->vval.v_job;
Bram Moolenaar839fd112016-03-06 21:34:03 +01006710 char *status;
6711
6712 if (job == NULL)
6713 return (char_u *)"no process";
6714 status = job->jv_status == JOB_FAILED ? "fail"
Bram Moolenaar7df915d2016-11-17 17:25:32 +01006715 : job->jv_status >= JOB_ENDED ? "dead"
Bram Moolenaar835dc632016-02-07 14:27:38 +01006716 : "run";
6717# ifdef UNIX
6718 vim_snprintf((char *)buf, NUMBUFLEN,
6719 "process %ld %s", (long)job->jv_pid, status);
Bram Moolenaar4f974752019-02-17 17:44:42 +01006720# elif defined(MSWIN)
Bram Moolenaar4d8747c2016-02-09 20:39:26 +01006721 vim_snprintf((char *)buf, NUMBUFLEN,
Bram Moolenaar76467df2016-02-12 19:30:26 +01006722 "process %ld %s",
6723 (long)job->jv_proc_info.dwProcessId,
Bram Moolenaar4d8747c2016-02-09 20:39:26 +01006724 status);
Bram Moolenaar835dc632016-02-07 14:27:38 +01006725# else
Bram Moolenaar4d8747c2016-02-09 20:39:26 +01006726 /* fall-back */
Bram Moolenaar835dc632016-02-07 14:27:38 +01006727 vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
6728# endif
6729 return buf;
6730 }
6731#endif
6732 break;
Bram Moolenaar77073442016-02-13 23:23:53 +01006733 case VAR_CHANNEL:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01006734#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar77073442016-02-13 23:23:53 +01006735 {
6736 channel_T *channel = varp->vval.v_channel;
Bram Moolenaar0e77b762016-09-26 22:58:58 +02006737 char *status = channel_status(channel, -1);
Bram Moolenaar77073442016-02-13 23:23:53 +01006738
Bram Moolenaar5cefd402016-02-16 12:44:26 +01006739 if (channel == NULL)
6740 vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
6741 else
6742 vim_snprintf((char *)buf, NUMBUFLEN,
Bram Moolenaar77073442016-02-13 23:23:53 +01006743 "channel %d %s", channel->ch_id, status);
6744 return buf;
6745 }
6746#endif
6747 break;
Bram Moolenaara03f2332016-02-06 18:09:59 +01006748 case VAR_UNKNOWN:
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006749 emsg(_("E908: using an invalid value as a String"));
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006750 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006751 }
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +00006752 return NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006753}
6754
6755/*
Bram Moolenaar461a7fc2018-12-22 13:28:07 +01006756 * Turn a typeval into a string. Similar to tv_get_string_buf() but uses
6757 * string() on Dict, List, etc.
6758 */
Bram Moolenaar5843f5f2019-08-20 20:13:45 +02006759 static char_u *
Bram Moolenaar461a7fc2018-12-22 13:28:07 +01006760tv_stringify(typval_T *varp, char_u *buf)
6761{
6762 if (varp->v_type == VAR_LIST
6763 || varp->v_type == VAR_DICT
6764 || varp->v_type == VAR_FUNC
6765 || varp->v_type == VAR_PARTIAL
6766 || varp->v_type == VAR_FLOAT)
6767 {
6768 typval_T tmp;
6769
6770 f_string(varp, &tmp);
6771 tv_get_string_buf(&tmp, buf);
6772 clear_tv(varp);
6773 *varp = tmp;
6774 return tmp.vval.v_string;
6775 }
6776 return tv_get_string_buf(varp, buf);
6777}
6778
6779/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006780 * Find variable "name" in the list of variables.
6781 * Return a pointer to it if found, NULL if not found.
Bram Moolenaar49cd9572005-01-03 21:06:01 +00006782 * Careful: "a:0" variables don't have a name.
Bram Moolenaara7043832005-01-21 11:56:39 +00006783 * When "htp" is not NULL we are writing to the variable, set "htp" to the
Bram Moolenaar33570922005-01-25 22:26:29 +00006784 * hashtab_T used.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006785 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006786 dictitem_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006787find_var(char_u *name, hashtab_T **htp, int no_autoload)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006788{
Bram Moolenaar071d4272004-06-13 20:20:40 +00006789 char_u *varname;
Bram Moolenaar33570922005-01-25 22:26:29 +00006790 hashtab_T *ht;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006791 dictitem_T *ret = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006792
Bram Moolenaara7043832005-01-21 11:56:39 +00006793 ht = find_var_ht(name, &varname);
6794 if (htp != NULL)
6795 *htp = ht;
6796 if (ht == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006797 return NULL;
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006798 ret = find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
6799 if (ret != NULL)
6800 return ret;
6801
6802 /* Search in parent scope for lambda */
Bram Moolenaarba96e9a2016-08-01 17:10:20 +02006803 return find_var_in_scoped_ht(name, no_autoload || htp != NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006804}
6805
6806/*
Bram Moolenaar332ac062013-04-15 13:06:21 +02006807 * Find variable "varname" in hashtab "ht" with name "htname".
Bram Moolenaara7043832005-01-21 11:56:39 +00006808 * Returns NULL if not found.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006809 */
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02006810 dictitem_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006811find_var_in_ht(
6812 hashtab_T *ht,
6813 int htname,
6814 char_u *varname,
6815 int no_autoload)
Bram Moolenaara7043832005-01-21 11:56:39 +00006816{
Bram Moolenaar33570922005-01-25 22:26:29 +00006817 hashitem_T *hi;
6818
6819 if (*varname == NUL)
6820 {
6821 /* Must be something like "s:", otherwise "ht" would be NULL. */
Bram Moolenaar332ac062013-04-15 13:06:21 +02006822 switch (htname)
Bram Moolenaar33570922005-01-25 22:26:29 +00006823 {
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02006824 case 's': return &SCRIPT_SV(current_sctx.sc_sid)->sv_var;
Bram Moolenaar33570922005-01-25 22:26:29 +00006825 case 'g': return &globvars_var;
6826 case 'v': return &vimvars_var;
6827 case 'b': return &curbuf->b_bufvar;
6828 case 'w': return &curwin->w_winvar;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006829 case 't': return &curtab->tp_winvar;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006830 case 'l': return get_funccal_local_var();
6831 case 'a': return get_funccal_args_var();
Bram Moolenaar33570922005-01-25 22:26:29 +00006832 }
6833 return NULL;
6834 }
Bram Moolenaara7043832005-01-21 11:56:39 +00006835
6836 hi = hash_find(ht, varname);
6837 if (HASHITEM_EMPTY(hi))
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00006838 {
6839 /* For global variables we may try auto-loading the script. If it
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00006840 * worked find the variable again. Don't auto-load a script if it was
6841 * loaded already, otherwise it would be loaded every time when
6842 * checking if a function name is a Funcref variable. */
Bram Moolenaar6d977d62014-01-14 15:24:39 +01006843 if (ht == &globvarht && !no_autoload)
Bram Moolenaar8000baf2011-11-30 15:19:28 +01006844 {
6845 /* Note: script_autoload() may make "hi" invalid. It must either
6846 * be obtained again or not used. */
6847 if (!script_autoload(varname, FALSE) || aborting())
6848 return NULL;
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00006849 hi = hash_find(ht, varname);
Bram Moolenaar8000baf2011-11-30 15:19:28 +01006850 }
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00006851 if (HASHITEM_EMPTY(hi))
6852 return NULL;
6853 }
Bram Moolenaar33570922005-01-25 22:26:29 +00006854 return HI2DI(hi);
Bram Moolenaara7043832005-01-21 11:56:39 +00006855}
6856
6857/*
Bram Moolenaar33570922005-01-25 22:26:29 +00006858 * Find the hashtab used for a variable name.
Bram Moolenaar73627d02015-08-11 15:46:09 +02006859 * Return NULL if the name is not valid.
Bram Moolenaara7043832005-01-21 11:56:39 +00006860 * Set "varname" to the start of name without ':'.
6861 */
Bram Moolenaar1e96d9b2016-07-29 22:15:09 +02006862 hashtab_T *
Bram Moolenaar7454a062016-01-30 15:14:10 +01006863find_var_ht(char_u *name, char_u **varname)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006864{
Bram Moolenaar75c50c42005-06-04 22:06:24 +00006865 hashitem_T *hi;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006866 hashtab_T *ht;
Bram Moolenaar75c50c42005-06-04 22:06:24 +00006867
Bram Moolenaar73627d02015-08-11 15:46:09 +02006868 if (name[0] == NUL)
6869 return NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006870 if (name[1] != ':')
6871 {
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00006872 /* The name must not start with a colon or #. */
6873 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006874 return NULL;
6875 *varname = name;
Bram Moolenaar532c7802005-01-27 14:44:31 +00006876
Bram Moolenaard2e716e2019-04-20 14:39:52 +02006877 // "version" is "v:version" in all scopes if scriptversion < 3.
6878 // Same for a few other variables marked with VV_COMPAT.
6879 if (current_sctx.sc_version < 3)
6880 {
6881 hi = hash_find(&compat_hashtab, name);
6882 if (!HASHITEM_EMPTY(hi))
6883 return &compat_hashtab;
6884 }
Bram Moolenaar532c7802005-01-27 14:44:31 +00006885
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006886 ht = get_funccal_local_ht();
6887 if (ht == NULL)
Bram Moolenaar33570922005-01-25 22:26:29 +00006888 return &globvarht; /* global variable */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006889 return ht; /* local variable */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006890 }
6891 *varname = name + 2;
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00006892 if (*name == 'g') /* global variable */
6893 return &globvarht;
Bram Moolenaar4c6d9042019-07-16 22:04:02 +02006894 // There must be no ':' or '#' in the rest of the name, unless g: is used
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00006895 if (vim_strchr(name + 2, ':') != NULL
6896 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00006897 return NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006898 if (*name == 'b') /* buffer variable */
Bram Moolenaar429fa852013-04-15 12:27:36 +02006899 return &curbuf->b_vars->dv_hashtab;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006900 if (*name == 'w') /* window variable */
Bram Moolenaar429fa852013-04-15 12:27:36 +02006901 return &curwin->w_vars->dv_hashtab;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006902 if (*name == 't') /* tab page variable */
Bram Moolenaar429fa852013-04-15 12:27:36 +02006903 return &curtab->tp_vars->dv_hashtab;
Bram Moolenaar33570922005-01-25 22:26:29 +00006904 if (*name == 'v') /* v: variable */
6905 return &vimvarht;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02006906 if (*name == 'a') /* a: function argument */
6907 return get_funccal_args_ht();
6908 if (*name == 'l') /* l: local function variable */
6909 return get_funccal_local_ht();
Bram Moolenaar071d4272004-06-13 20:20:40 +00006910 if (*name == 's' /* script variable */
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02006911 && current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len)
6912 return &SCRIPT_VARS(current_sctx.sc_sid);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006913 return NULL;
6914}
6915
6916/*
Bram Moolenaar33570922005-01-25 22:26:29 +00006917 * Allocate a new hashtab for a sourced script. It will be used while
Bram Moolenaar071d4272004-06-13 20:20:40 +00006918 * sourcing this script and when executing functions defined in the script.
6919 */
6920 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006921new_script_vars(scid_T id)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006922{
Bram Moolenaara7043832005-01-21 11:56:39 +00006923 int i;
Bram Moolenaar33570922005-01-25 22:26:29 +00006924 hashtab_T *ht;
6925 scriptvar_T *sv;
Bram Moolenaara7043832005-01-21 11:56:39 +00006926
Bram Moolenaar071d4272004-06-13 20:20:40 +00006927 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
6928 {
Bram Moolenaara7043832005-01-21 11:56:39 +00006929 /* Re-allocating ga_data means that an ht_array pointing to
6930 * ht_smallarray becomes invalid. We can recognize this: ht_mask is
Bram Moolenaar33570922005-01-25 22:26:29 +00006931 * at its init value. Also reset "v_dict", it's always the same. */
Bram Moolenaara7043832005-01-21 11:56:39 +00006932 for (i = 1; i <= ga_scripts.ga_len; ++i)
6933 {
6934 ht = &SCRIPT_VARS(i);
6935 if (ht->ht_mask == HT_INIT_SIZE - 1)
6936 ht->ht_array = ht->ht_smallarray;
Bram Moolenaar9577c3e2010-05-14 12:16:25 +02006937 sv = SCRIPT_SV(i);
Bram Moolenaar33570922005-01-25 22:26:29 +00006938 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
Bram Moolenaara7043832005-01-21 11:56:39 +00006939 }
6940
Bram Moolenaar071d4272004-06-13 20:20:40 +00006941 while (ga_scripts.ga_len < id)
6942 {
Bram Moolenaar2c704a72010-06-03 21:17:25 +02006943 sv = SCRIPT_SV(ga_scripts.ga_len + 1) =
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006944 ALLOC_CLEAR_ONE(scriptvar_T);
Bram Moolenaarbdb62052012-07-16 17:31:53 +02006945 init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006946 ++ga_scripts.ga_len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006947 }
6948 }
6949}
6950
6951/*
Bram Moolenaar33570922005-01-25 22:26:29 +00006952 * Initialize dictionary "dict" as a scope and set variable "dict_var" to
6953 * point to it.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006954 */
6955 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006956init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006957{
Bram Moolenaar33570922005-01-25 22:26:29 +00006958 hash_init(&dict->dv_hashtab);
Bram Moolenaared465602012-06-20 14:13:06 +02006959 dict->dv_lock = 0;
Bram Moolenaarbdb62052012-07-16 17:31:53 +02006960 dict->dv_scope = scope;
Bram Moolenaar8ba1bd22008-12-23 22:52:58 +00006961 dict->dv_refcount = DO_NOT_FREE_CNT;
Bram Moolenaarc0a6fac2009-05-24 11:40:58 +00006962 dict->dv_copyID = 0;
Bram Moolenaar33570922005-01-25 22:26:29 +00006963 dict_var->di_tv.vval.v_dict = dict;
6964 dict_var->di_tv.v_type = VAR_DICT;
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00006965 dict_var->di_tv.v_lock = VAR_FIXED;
Bram Moolenaar33570922005-01-25 22:26:29 +00006966 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
6967 dict_var->di_key[0] = NUL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006968}
6969
6970/*
Bram Moolenaar429fa852013-04-15 12:27:36 +02006971 * Unreference a dictionary initialized by init_var_dict().
6972 */
6973 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01006974unref_var_dict(dict_T *dict)
Bram Moolenaar429fa852013-04-15 12:27:36 +02006975{
6976 /* Now the dict needs to be freed if no one else is using it, go back to
6977 * normal reference counting. */
6978 dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
6979 dict_unref(dict);
6980}
6981
6982/*
Bram Moolenaar05c00c02019-02-11 22:00:11 +01006983 * Return TRUE if typeval "tv" and its value are set to be locked (immutable).
6984 * Also give an error message, using "name" or _("name") when use_gettext is
6985 * TRUE.
6986 */
6987 static int
6988tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
6989{
6990 int lock = 0;
6991
6992 switch (tv->v_type)
6993 {
6994 case VAR_BLOB:
6995 if (tv->vval.v_blob != NULL)
6996 lock = tv->vval.v_blob->bv_lock;
6997 break;
6998 case VAR_LIST:
6999 if (tv->vval.v_list != NULL)
7000 lock = tv->vval.v_list->lv_lock;
7001 break;
7002 case VAR_DICT:
7003 if (tv->vval.v_dict != NULL)
7004 lock = tv->vval.v_dict->dv_lock;
7005 break;
7006 default:
7007 break;
7008 }
7009 return var_check_lock(tv->v_lock, name, use_gettext)
7010 || (lock != 0 && var_check_lock(lock, name, use_gettext));
7011}
7012
7013/*
Bram Moolenaar33570922005-01-25 22:26:29 +00007014 * Copy the values from typval_T "from" to typval_T "to".
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007015 * When needed allocates string or increases reference count.
Bram Moolenaardd29ea12019-01-23 21:56:21 +01007016 * Does not make a copy of a list, blob or dict but copies the reference!
Bram Moolenaar8ba1bd22008-12-23 22:52:58 +00007017 * It is OK for "from" and "to" to point to the same item. This is used to
7018 * make a copy later.
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007019 */
Bram Moolenaar7e506b62010-01-19 15:55:06 +01007020 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01007021copy_tv(typval_T *from, typval_T *to)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007022{
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007023 to->v_type = from->v_type;
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00007024 to->v_lock = 0;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007025 switch (from->v_type)
7026 {
7027 case VAR_NUMBER:
Bram Moolenaar520e1e42016-01-23 19:46:28 +01007028 case VAR_SPECIAL:
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007029 to->vval.v_number = from->vval.v_number;
7030 break;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00007031 case VAR_FLOAT:
Bram Moolenaar835dc632016-02-07 14:27:38 +01007032#ifdef FEAT_FLOAT
Bram Moolenaar8c8de832008-06-24 22:58:06 +00007033 to->vval.v_float = from->vval.v_float;
7034 break;
7035#endif
Bram Moolenaar835dc632016-02-07 14:27:38 +01007036 case VAR_JOB:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01007037#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar835dc632016-02-07 14:27:38 +01007038 to->vval.v_job = from->vval.v_job;
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01007039 if (to->vval.v_job != NULL)
7040 ++to->vval.v_job->jv_refcount;
Bram Moolenaar835dc632016-02-07 14:27:38 +01007041 break;
7042#endif
Bram Moolenaar77073442016-02-13 23:23:53 +01007043 case VAR_CHANNEL:
Bram Moolenaar509ce2a2016-03-11 22:52:15 +01007044#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar77073442016-02-13 23:23:53 +01007045 to->vval.v_channel = from->vval.v_channel;
Bram Moolenaar5cefd402016-02-16 12:44:26 +01007046 if (to->vval.v_channel != NULL)
7047 ++to->vval.v_channel->ch_refcount;
Bram Moolenaar77073442016-02-13 23:23:53 +01007048 break;
7049#endif
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007050 case VAR_STRING:
7051 case VAR_FUNC:
7052 if (from->vval.v_string == NULL)
7053 to->vval.v_string = NULL;
7054 else
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00007055 {
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007056 to->vval.v_string = vim_strsave(from->vval.v_string);
Bram Moolenaar9ef486d2005-01-17 22:23:00 +00007057 if (from->v_type == VAR_FUNC)
7058 func_ref(to->vval.v_string);
7059 }
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007060 break;
Bram Moolenaar1735bc92016-03-14 23:05:14 +01007061 case VAR_PARTIAL:
7062 if (from->vval.v_partial == NULL)
7063 to->vval.v_partial = NULL;
7064 else
7065 {
7066 to->vval.v_partial = from->vval.v_partial;
7067 ++to->vval.v_partial->pt_refcount;
7068 }
7069 break;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01007070 case VAR_BLOB:
7071 if (from->vval.v_blob == NULL)
7072 to->vval.v_blob = NULL;
7073 else
7074 {
7075 to->vval.v_blob = from->vval.v_blob;
7076 ++to->vval.v_blob->bv_refcount;
7077 }
7078 break;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007079 case VAR_LIST:
7080 if (from->vval.v_list == NULL)
7081 to->vval.v_list = NULL;
7082 else
7083 {
7084 to->vval.v_list = from->vval.v_list;
7085 ++to->vval.v_list->lv_refcount;
7086 }
7087 break;
Bram Moolenaar8c711452005-01-14 21:53:12 +00007088 case VAR_DICT:
7089 if (from->vval.v_dict == NULL)
7090 to->vval.v_dict = NULL;
7091 else
7092 {
7093 to->vval.v_dict = from->vval.v_dict;
7094 ++to->vval.v_dict->dv_refcount;
7095 }
7096 break;
Bram Moolenaara03f2332016-02-06 18:09:59 +01007097 case VAR_UNKNOWN:
Bram Moolenaar95f09602016-11-10 20:01:45 +01007098 internal_error("copy_tv(UNKNOWN)");
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007099 break;
7100 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00007101}
7102
7103/*
Bram Moolenaare9a41262005-01-15 22:18:47 +00007104 * Make a copy of an item.
7105 * Lists and Dictionaries are also copied. A deep copy if "deep" is set.
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007106 * For deepcopy() "copyID" is zero for a full copy or the ID for when a
7107 * reference to an already copied list/dict can be used.
7108 * Returns FAIL or OK.
Bram Moolenaare9a41262005-01-15 22:18:47 +00007109 */
Bram Moolenaarcd524592016-07-17 14:57:05 +02007110 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01007111item_copy(
7112 typval_T *from,
7113 typval_T *to,
7114 int deep,
7115 int copyID)
Bram Moolenaare9a41262005-01-15 22:18:47 +00007116{
7117 static int recurse = 0;
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007118 int ret = OK;
Bram Moolenaare9a41262005-01-15 22:18:47 +00007119
Bram Moolenaar33570922005-01-25 22:26:29 +00007120 if (recurse >= DICT_MAXNEST)
Bram Moolenaare9a41262005-01-15 22:18:47 +00007121 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007122 emsg(_("E698: variable nested too deep for making a copy"));
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007123 return FAIL;
Bram Moolenaare9a41262005-01-15 22:18:47 +00007124 }
7125 ++recurse;
7126
7127 switch (from->v_type)
7128 {
7129 case VAR_NUMBER:
Bram Moolenaar8c8de832008-06-24 22:58:06 +00007130 case VAR_FLOAT:
Bram Moolenaare9a41262005-01-15 22:18:47 +00007131 case VAR_STRING:
7132 case VAR_FUNC:
Bram Moolenaar1735bc92016-03-14 23:05:14 +01007133 case VAR_PARTIAL:
Bram Moolenaar15550002016-01-31 18:45:24 +01007134 case VAR_SPECIAL:
Bram Moolenaar835dc632016-02-07 14:27:38 +01007135 case VAR_JOB:
Bram Moolenaar77073442016-02-13 23:23:53 +01007136 case VAR_CHANNEL:
Bram Moolenaare9a41262005-01-15 22:18:47 +00007137 copy_tv(from, to);
7138 break;
7139 case VAR_LIST:
7140 to->v_type = VAR_LIST;
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00007141 to->v_lock = 0;
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007142 if (from->vval.v_list == NULL)
7143 to->vval.v_list = NULL;
7144 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID)
7145 {
7146 /* use the copy made earlier */
7147 to->vval.v_list = from->vval.v_list->lv_copylist;
7148 ++to->vval.v_list->lv_refcount;
7149 }
7150 else
7151 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID);
7152 if (to->vval.v_list == NULL)
7153 ret = FAIL;
Bram Moolenaare9a41262005-01-15 22:18:47 +00007154 break;
Bram Moolenaar3d28b582019-01-15 22:44:17 +01007155 case VAR_BLOB:
Bram Moolenaardd29ea12019-01-23 21:56:21 +01007156 ret = blob_copy(from, to);
Bram Moolenaar3d28b582019-01-15 22:44:17 +01007157 break;
Bram Moolenaare9a41262005-01-15 22:18:47 +00007158 case VAR_DICT:
7159 to->v_type = VAR_DICT;
Bram Moolenaar2e6aff32005-01-31 19:25:36 +00007160 to->v_lock = 0;
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007161 if (from->vval.v_dict == NULL)
7162 to->vval.v_dict = NULL;
7163 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID)
7164 {
7165 /* use the copy made earlier */
7166 to->vval.v_dict = from->vval.v_dict->dv_copydict;
7167 ++to->vval.v_dict->dv_refcount;
7168 }
7169 else
7170 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID);
7171 if (to->vval.v_dict == NULL)
7172 ret = FAIL;
Bram Moolenaare9a41262005-01-15 22:18:47 +00007173 break;
Bram Moolenaara03f2332016-02-06 18:09:59 +01007174 case VAR_UNKNOWN:
Bram Moolenaar95f09602016-11-10 20:01:45 +01007175 internal_error("item_copy(UNKNOWN)");
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007176 ret = FAIL;
Bram Moolenaare9a41262005-01-15 22:18:47 +00007177 }
7178 --recurse;
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007179 return ret;
Bram Moolenaare9a41262005-01-15 22:18:47 +00007180}
7181
7182/*
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007183 * This function is used by f_input() and f_inputdialog() functions. The third
7184 * argument to f_input() specifies the type of completion to use at the
7185 * prompt. The third argument to f_inputdialog() specifies the value to return
7186 * when the user cancels the prompt.
7187 */
7188 void
7189get_user_input(
7190 typval_T *argvars,
7191 typval_T *rettv,
7192 int inputdialog,
7193 int secret)
7194{
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007195 char_u *prompt = tv_get_string_chk(&argvars[0]);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007196 char_u *p = NULL;
7197 int c;
7198 char_u buf[NUMBUFLEN];
7199 int cmd_silent_save = cmd_silent;
7200 char_u *defstr = (char_u *)"";
7201 int xp_type = EXPAND_NOTHING;
7202 char_u *xp_arg = NULL;
7203
7204 rettv->v_type = VAR_STRING;
7205 rettv->vval.v_string = NULL;
7206
7207#ifdef NO_CONSOLE_INPUT
Bram Moolenaar91d348a2017-07-29 20:16:03 +02007208 /* While starting up, there is no place to enter text. When running tests
7209 * with --not-a-term we assume feedkeys() will be used. */
7210 if (no_console_input() && !is_not_a_term())
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007211 return;
7212#endif
7213
7214 cmd_silent = FALSE; /* Want to see the prompt. */
7215 if (prompt != NULL)
7216 {
7217 /* Only the part of the message after the last NL is considered as
7218 * prompt for the command line */
7219 p = vim_strrchr(prompt, '\n');
7220 if (p == NULL)
7221 p = prompt;
7222 else
7223 {
7224 ++p;
7225 c = *p;
7226 *p = NUL;
7227 msg_start();
7228 msg_clr_eos();
Bram Moolenaar32526b32019-01-19 17:43:09 +01007229 msg_puts_attr((char *)prompt, echo_attr);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007230 msg_didout = FALSE;
7231 msg_starthere();
7232 *p = c;
7233 }
7234 cmdline_row = msg_row;
7235
7236 if (argvars[1].v_type != VAR_UNKNOWN)
7237 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007238 defstr = tv_get_string_buf_chk(&argvars[1], buf);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007239 if (defstr != NULL)
7240 stuffReadbuffSpec(defstr);
7241
7242 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
7243 {
7244 char_u *xp_name;
7245 int xp_namelen;
7246 long argt;
7247
7248 /* input() with a third argument: completion */
7249 rettv->vval.v_string = NULL;
7250
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007251 xp_name = tv_get_string_buf_chk(&argvars[2], buf);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007252 if (xp_name == NULL)
7253 return;
7254
7255 xp_namelen = (int)STRLEN(xp_name);
7256
7257 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
7258 &xp_arg) == FAIL)
7259 return;
7260 }
7261 }
7262
7263 if (defstr != NULL)
7264 {
7265 int save_ex_normal_busy = ex_normal_busy;
Bram Moolenaar6dff58f2018-09-30 21:43:26 +02007266
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007267 ex_normal_busy = 0;
7268 rettv->vval.v_string =
7269 getcmdline_prompt(secret ? NUL : '@', p, echo_attr,
7270 xp_type, xp_arg);
7271 ex_normal_busy = save_ex_normal_busy;
7272 }
7273 if (inputdialog && rettv->vval.v_string == NULL
7274 && argvars[1].v_type != VAR_UNKNOWN
7275 && argvars[2].v_type != VAR_UNKNOWN)
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007276 rettv->vval.v_string = vim_strsave(tv_get_string_buf(
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007277 &argvars[2], buf));
7278
7279 vim_free(xp_arg);
7280
7281 /* since the user typed this, no need to wait for return */
7282 need_wait_return = FALSE;
7283 msg_didout = FALSE;
7284 }
7285 cmd_silent = cmd_silent_save;
7286}
7287
7288/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00007289 * ":echo expr1 ..." print each argument separated with a space, add a
7290 * newline at the end.
7291 * ":echon expr1 ..." print each argument plain.
7292 */
7293 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01007294ex_echo(exarg_T *eap)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007295{
7296 char_u *arg = eap->arg;
Bram Moolenaar33570922005-01-25 22:26:29 +00007297 typval_T rettv;
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007298 char_u *tofree;
Bram Moolenaar071d4272004-06-13 20:20:40 +00007299 char_u *p;
7300 int needclr = TRUE;
7301 int atstart = TRUE;
Bram Moolenaar8a283e52005-01-06 23:28:25 +00007302 char_u numbuf[NUMBUFLEN];
Bram Moolenaar76a63452018-11-28 20:38:37 +01007303 int did_emsg_before = did_emsg;
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01007304 int called_emsg_before = called_emsg;
Bram Moolenaar071d4272004-06-13 20:20:40 +00007305
7306 if (eap->skip)
7307 ++emsg_skip;
7308 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
7309 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00007310 /* If eval1() causes an error message the text from the command may
7311 * still need to be cleared. E.g., "echo 22,44". */
7312 need_clr_eos = needclr;
7313
Bram Moolenaar071d4272004-06-13 20:20:40 +00007314 p = arg;
Bram Moolenaarc70646c2005-01-04 21:52:38 +00007315 if (eval1(&arg, &rettv, !eap->skip) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007316 {
7317 /*
7318 * Report the invalid expression unless the expression evaluation
7319 * has been cancelled due to an aborting error, an interrupt, or an
7320 * exception.
7321 */
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01007322 if (!aborting() && did_emsg == did_emsg_before
7323 && called_emsg == called_emsg_before)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007324 semsg(_(e_invexpr2), p);
Bram Moolenaar8c8de832008-06-24 22:58:06 +00007325 need_clr_eos = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00007326 break;
7327 }
Bram Moolenaar8c8de832008-06-24 22:58:06 +00007328 need_clr_eos = FALSE;
7329
Bram Moolenaar071d4272004-06-13 20:20:40 +00007330 if (!eap->skip)
7331 {
7332 if (atstart)
7333 {
7334 atstart = FALSE;
7335 /* Call msg_start() after eval1(), evaluating the expression
7336 * may cause a message to appear. */
7337 if (eap->cmdidx == CMD_echo)
Bram Moolenaar12b02902012-03-23 15:18:24 +01007338 {
Bram Moolenaar6df5e5a2012-03-28 16:49:29 +02007339 /* Mark the saved text as finishing the line, so that what
7340 * follows is displayed on a new line when scrolling back
7341 * at the more prompt. */
7342 msg_sb_eol();
Bram Moolenaar071d4272004-06-13 20:20:40 +00007343 msg_start();
Bram Moolenaar12b02902012-03-23 15:18:24 +01007344 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00007345 }
7346 else if (eap->cmdidx == CMD_echo)
Bram Moolenaar32526b32019-01-19 17:43:09 +01007347 msg_puts_attr(" ", echo_attr);
Bram Moolenaar520e1e42016-01-23 19:46:28 +01007348 p = echo_string(&rettv, &tofree, numbuf, get_copyID());
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007349 if (p != NULL)
7350 for ( ; *p != NUL && !got_int; ++p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007351 {
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007352 if (*p == '\n' || *p == '\r' || *p == TAB)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007353 {
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007354 if (*p != TAB && needclr)
7355 {
7356 /* remove any text still there from the command */
7357 msg_clr_eos();
7358 needclr = FALSE;
7359 }
7360 msg_putchar_attr(*p, echo_attr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007361 }
7362 else
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007363 {
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007364 if (has_mbyte)
7365 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00007366 int i = (*mb_ptr2len)(p);
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007367
7368 (void)msg_outtrans_len_attr(p, i, echo_attr);
7369 p += i - 1;
7370 }
7371 else
Bram Moolenaar81bf7082005-02-12 14:31:42 +00007372 (void)msg_outtrans_len_attr(p, 1, echo_attr);
7373 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00007374 }
Bram Moolenaar49cd9572005-01-03 21:06:01 +00007375 vim_free(tofree);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007376 }
Bram Moolenaarc70646c2005-01-04 21:52:38 +00007377 clear_tv(&rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007378 arg = skipwhite(arg);
7379 }
7380 eap->nextcmd = check_nextcmd(arg);
7381
7382 if (eap->skip)
7383 --emsg_skip;
7384 else
7385 {
7386 /* remove text that may still be there from the command */
7387 if (needclr)
7388 msg_clr_eos();
7389 if (eap->cmdidx == CMD_echo)
7390 msg_end();
7391 }
7392}
7393
7394/*
7395 * ":echohl {name}".
7396 */
7397 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01007398ex_echohl(exarg_T *eap)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007399{
Bram Moolenaar1b9645d2017-09-17 23:03:31 +02007400 echo_attr = syn_name2attr(eap->arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007401}
7402
7403/*
7404 * ":execute expr1 ..." execute the result of an expression.
7405 * ":echomsg expr1 ..." Print a message
7406 * ":echoerr expr1 ..." Print an error
7407 * Each gets spaces around each argument and a newline at the end for
7408 * echo commands
7409 */
7410 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01007411ex_execute(exarg_T *eap)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007412{
7413 char_u *arg = eap->arg;
Bram Moolenaar33570922005-01-25 22:26:29 +00007414 typval_T rettv;
Bram Moolenaar071d4272004-06-13 20:20:40 +00007415 int ret = OK;
7416 char_u *p;
7417 garray_T ga;
7418 int len;
Bram Moolenaar2c519cf2019-03-21 21:45:34 +01007419 int save_did_emsg;
Bram Moolenaar071d4272004-06-13 20:20:40 +00007420
7421 ga_init2(&ga, 1, 80);
7422
7423 if (eap->skip)
7424 ++emsg_skip;
7425 while (*arg != NUL && *arg != '|' && *arg != '\n')
7426 {
Bram Moolenaarce9d50d2019-01-14 22:22:29 +01007427 ret = eval1_emsg(&arg, &rettv, !eap->skip);
7428 if (ret == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007429 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00007430
7431 if (!eap->skip)
7432 {
Bram Moolenaar461a7fc2018-12-22 13:28:07 +01007433 char_u buf[NUMBUFLEN];
7434
7435 if (eap->cmdidx == CMD_execute)
7436 p = tv_get_string_buf(&rettv, buf);
7437 else
7438 p = tv_stringify(&rettv, buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007439 len = (int)STRLEN(p);
7440 if (ga_grow(&ga, len + 2) == FAIL)
7441 {
Bram Moolenaarc70646c2005-01-04 21:52:38 +00007442 clear_tv(&rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007443 ret = FAIL;
7444 break;
7445 }
7446 if (ga.ga_len)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007447 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
Bram Moolenaar071d4272004-06-13 20:20:40 +00007448 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007449 ga.ga_len += len;
7450 }
7451
Bram Moolenaarc70646c2005-01-04 21:52:38 +00007452 clear_tv(&rettv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007453 arg = skipwhite(arg);
7454 }
7455
7456 if (ret != FAIL && ga.ga_data != NULL)
7457 {
Bram Moolenaar57002ad2017-03-16 19:04:19 +01007458 if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr)
7459 {
7460 /* Mark the already saved text as finishing the line, so that what
7461 * follows is displayed on a new line when scrolling back at the
7462 * more prompt. */
7463 msg_sb_eol();
Bram Moolenaar57002ad2017-03-16 19:04:19 +01007464 }
7465
Bram Moolenaar071d4272004-06-13 20:20:40 +00007466 if (eap->cmdidx == CMD_echomsg)
Bram Moolenaar4770d092006-01-12 23:22:24 +00007467 {
Bram Moolenaar32526b32019-01-19 17:43:09 +01007468 msg_attr(ga.ga_data, echo_attr);
Bram Moolenaar4770d092006-01-12 23:22:24 +00007469 out_flush();
7470 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00007471 else if (eap->cmdidx == CMD_echoerr)
7472 {
7473 /* We don't want to abort following commands, restore did_emsg. */
7474 save_did_emsg = did_emsg;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007475 emsg(ga.ga_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +00007476 if (!force_abort)
7477 did_emsg = save_did_emsg;
7478 }
7479 else if (eap->cmdidx == CMD_execute)
7480 do_cmdline((char_u *)ga.ga_data,
7481 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
7482 }
7483
7484 ga_clear(&ga);
7485
7486 if (eap->skip)
7487 --emsg_skip;
7488
7489 eap->nextcmd = check_nextcmd(arg);
7490}
7491
7492/*
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007493 * Find window specified by "vp" in tabpage "tp".
7494 */
7495 win_T *
7496find_win_by_nr(
7497 typval_T *vp,
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007498 tabpage_T *tp) /* NULL for current tab page */
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007499{
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007500 win_T *wp;
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007501 int nr = (int)tv_get_number_chk(vp, NULL);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007502
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007503 if (nr < 0)
7504 return NULL;
7505 if (nr == 0)
7506 return curwin;
7507
Bram Moolenaar29323592016-07-24 22:04:11 +02007508 FOR_ALL_WINDOWS_IN_TAB(tp, wp)
7509 {
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007510 if (nr >= LOWEST_WIN_ID)
7511 {
7512 if (wp->w_id == nr)
7513 return wp;
7514 }
7515 else if (--nr <= 0)
7516 break;
Bram Moolenaar29323592016-07-24 22:04:11 +02007517 }
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007518 if (nr >= LOWEST_WIN_ID)
Bram Moolenaar4d784b22019-05-25 19:51:39 +02007519 {
7520#ifdef FEAT_TEXT_PROP
Bram Moolenaar9c27b1c2019-05-26 18:48:13 +02007521 // check tab-local popup windows
7522 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
Bram Moolenaar4d784b22019-05-25 19:51:39 +02007523 if (wp->w_id == nr)
7524 return wp;
Bram Moolenaar9c27b1c2019-05-26 18:48:13 +02007525 // check global popup windows
Bram Moolenaar4d784b22019-05-25 19:51:39 +02007526 for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
7527 if (wp->w_id == nr)
7528 return wp;
7529#endif
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007530 return NULL;
Bram Moolenaar4d784b22019-05-25 19:51:39 +02007531 }
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007532 return wp;
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007533}
7534
7535/*
Bram Moolenaare6e39892018-10-25 12:32:11 +02007536 * Find a window: When using a Window ID in any tab page, when using a number
7537 * in the current tab page.
7538 */
7539 win_T *
7540find_win_by_nr_or_id(typval_T *vp)
7541{
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007542 int nr = (int)tv_get_number_chk(vp, NULL);
Bram Moolenaare6e39892018-10-25 12:32:11 +02007543
7544 if (nr >= LOWEST_WIN_ID)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01007545 return win_id2wp(tv_get_number(vp));
Bram Moolenaare6e39892018-10-25 12:32:11 +02007546 return find_win_by_nr(vp, NULL);
7547}
7548
7549/*
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007550 * Find window specified by "wvp" in tabpage "tvp".
Bram Moolenaar00aa0692019-04-27 20:37:57 +02007551 * Returns the tab page in 'ptp'
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007552 */
7553 win_T *
7554find_tabwin(
Bram Moolenaar00aa0692019-04-27 20:37:57 +02007555 typval_T *wvp, // VAR_UNKNOWN for current window
7556 typval_T *tvp, // VAR_UNKNOWN for current tab page
7557 tabpage_T **ptp)
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007558{
7559 win_T *wp = NULL;
7560 tabpage_T *tp = NULL;
7561 long n;
7562
7563 if (wvp->v_type != VAR_UNKNOWN)
7564 {
7565 if (tvp->v_type != VAR_UNKNOWN)
7566 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007567 n = (long)tv_get_number(tvp);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007568 if (n >= 0)
7569 tp = find_tabpage(n);
7570 }
7571 else
7572 tp = curtab;
7573
7574 if (tp != NULL)
Bram Moolenaar00aa0692019-04-27 20:37:57 +02007575 {
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007576 wp = find_win_by_nr(wvp, tp);
Bram Moolenaar00aa0692019-04-27 20:37:57 +02007577 if (wp == NULL && wvp->v_type == VAR_NUMBER
7578 && wvp->vval.v_number != -1)
7579 // A window with the specified number is not found
7580 tp = NULL;
7581 }
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007582 }
7583 else
Bram Moolenaar00aa0692019-04-27 20:37:57 +02007584 {
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007585 wp = curwin;
Bram Moolenaar00aa0692019-04-27 20:37:57 +02007586 tp = curtab;
7587 }
7588
7589 if (ptp != NULL)
7590 *ptp = tp;
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007591
7592 return wp;
7593}
7594
7595/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00007596 * Skip over the name of an option: "&option", "&g:option" or "&l:option".
7597 * "arg" points to the "&" or '+' when called, to "option" when returning.
7598 * Returns NULL when no option name found. Otherwise pointer to the char
7599 * after the option name.
7600 */
Bram Moolenaar0522ba02019-08-27 22:48:30 +02007601 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01007602find_option_end(char_u **arg, int *opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00007603{
7604 char_u *p = *arg;
7605
7606 ++p;
7607 if (*p == 'g' && p[1] == ':')
7608 {
7609 *opt_flags = OPT_GLOBAL;
7610 p += 2;
7611 }
7612 else if (*p == 'l' && p[1] == ':')
7613 {
7614 *opt_flags = OPT_LOCAL;
7615 p += 2;
7616 }
7617 else
7618 *opt_flags = 0;
7619
7620 if (!ASCII_ISALPHA(*p))
7621 return NULL;
7622 *arg = p;
7623
7624 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
7625 p += 4; /* termcap option */
7626 else
7627 while (ASCII_ISALPHA(*p))
7628 ++p;
7629 return p;
7630}
7631
7632/*
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007633 * Return the autoload script name for a function or variable name.
7634 * Returns NULL when out of memory.
Bram Moolenaar28fc2472019-07-05 22:14:16 +02007635 * Caller must make sure that "name" contains AUTOLOAD_CHAR.
Bram Moolenaar071d4272004-06-13 20:20:40 +00007636 */
Bram Moolenaara1544c02013-05-30 12:35:52 +02007637 char_u *
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007638autoload_name(char_u *name)
Bram Moolenaara1544c02013-05-30 12:35:52 +02007639{
Bram Moolenaar28fc2472019-07-05 22:14:16 +02007640 char_u *p, *q = NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007641 char_u *scriptname;
Bram Moolenaara1544c02013-05-30 12:35:52 +02007642
Bram Moolenaar28fc2472019-07-05 22:14:16 +02007643 // Get the script file name: replace '#' with '/', append ".vim".
Bram Moolenaar964b3742019-05-24 18:54:09 +02007644 scriptname = alloc(STRLEN(name) + 14);
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007645 if (scriptname == NULL)
Bram Moolenaar1058c9d2019-08-20 21:58:00 +02007646 return NULL;
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007647 STRCPY(scriptname, "autoload/");
7648 STRCAT(scriptname, name);
Bram Moolenaar28fc2472019-07-05 22:14:16 +02007649 for (p = scriptname + 9; (p = vim_strchr(p, AUTOLOAD_CHAR)) != NULL;
7650 q = p, ++p)
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007651 *p = '/';
Bram Moolenaar28fc2472019-07-05 22:14:16 +02007652 STRCPY(q, ".vim");
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007653 return scriptname;
Bram Moolenaarb11bd7e2005-02-07 22:05:52 +00007654}
7655
7656/*
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00007657 * If "name" has a package name try autoloading the script for it.
Bram Moolenaarb11bd7e2005-02-07 22:05:52 +00007658 * Return TRUE if a package was loaded.
7659 */
Bram Moolenaara9b579f2016-07-17 18:29:19 +02007660 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01007661script_autoload(
7662 char_u *name,
7663 int reload) /* load script again when already loaded */
Bram Moolenaarb11bd7e2005-02-07 22:05:52 +00007664{
7665 char_u *p;
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00007666 char_u *scriptname, *tofree;
Bram Moolenaarb11bd7e2005-02-07 22:05:52 +00007667 int ret = FALSE;
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00007668 int i;
Bram Moolenaarb11bd7e2005-02-07 22:05:52 +00007669
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00007670 /* If there is no '#' after name[0] there is no package name. */
Bram Moolenaar34cdc3e2005-05-18 22:24:46 +00007671 p = vim_strchr(name, AUTOLOAD_CHAR);
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00007672 if (p == NULL || p == name)
Bram Moolenaarb11bd7e2005-02-07 22:05:52 +00007673 return FALSE;
7674
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00007675 tofree = scriptname = autoload_name(name);
Bram Moolenaar1058c9d2019-08-20 21:58:00 +02007676 if (scriptname == NULL)
7677 return FALSE;
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00007678
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00007679 /* Find the name in the list of previously loaded package names. Skip
7680 * "autoload/", it's always the same. */
7681 for (i = 0; i < ga_loaded.ga_len; ++i)
7682 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
7683 break;
7684 if (!reload && i < ga_loaded.ga_len)
7685 ret = FALSE; /* was loaded already */
7686 else
7687 {
7688 /* Remember the name if it wasn't loaded already. */
7689 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
7690 {
7691 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
7692 tofree = NULL;
7693 }
7694
7695 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
Bram Moolenaar7f8989d2016-03-12 22:11:39 +01007696 if (source_runtime(scriptname, 0) == OK)
Bram Moolenaar87e25fd2005-07-27 21:13:01 +00007697 ret = TRUE;
7698 }
7699
7700 vim_free(tofree);
Bram Moolenaar5313dcb2005-02-22 08:56:13 +00007701 return ret;
7702}
7703
Bram Moolenaar661b1822005-07-28 22:36:45 +00007704/*
7705 * Display script name where an item was last set.
7706 * Should only be invoked when 'verbose' is non-zero.
7707 */
7708 void
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02007709last_set_msg(sctx_T script_ctx)
Bram Moolenaar661b1822005-07-28 22:36:45 +00007710{
Bram Moolenaarcafda4f2005-09-06 19:25:11 +00007711 char_u *p;
7712
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02007713 if (script_ctx.sc_sid != 0)
Bram Moolenaar661b1822005-07-28 22:36:45 +00007714 {
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02007715 p = home_replace_save(NULL, get_scriptname(script_ctx.sc_sid));
Bram Moolenaarcafda4f2005-09-06 19:25:11 +00007716 if (p != NULL)
7717 {
7718 verbose_enter();
Bram Moolenaar32526b32019-01-19 17:43:09 +01007719 msg_puts(_("\n\tLast set from "));
7720 msg_puts((char *)p);
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02007721 if (script_ctx.sc_lnum > 0)
7722 {
Bram Moolenaar32526b32019-01-19 17:43:09 +01007723 msg_puts(_(" line "));
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02007724 msg_outnum((long)script_ctx.sc_lnum);
7725 }
Bram Moolenaarcafda4f2005-09-06 19:25:11 +00007726 verbose_leave();
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02007727 vim_free(p);
Bram Moolenaarcafda4f2005-09-06 19:25:11 +00007728 }
Bram Moolenaar661b1822005-07-28 22:36:45 +00007729 }
7730}
7731
Bram Moolenaar61be3762019-03-19 23:04:17 +01007732/*
Bram Moolenaard7c96872019-06-15 17:12:48 +02007733 * reset v:option_new, v:option_old, v:option_oldlocal, v:option_oldglobal,
7734 * v:option_type, and v:option_command.
Bram Moolenaar61be3762019-03-19 23:04:17 +01007735 */
Bram Moolenaar53744302015-07-17 17:38:22 +02007736 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01007737reset_v_option_vars(void)
Bram Moolenaar53744302015-07-17 17:38:22 +02007738{
7739 set_vim_var_string(VV_OPTION_NEW, NULL, -1);
7740 set_vim_var_string(VV_OPTION_OLD, NULL, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02007741 set_vim_var_string(VV_OPTION_OLDLOCAL, NULL, -1);
7742 set_vim_var_string(VV_OPTION_OLDGLOBAL, NULL, -1);
Bram Moolenaar53744302015-07-17 17:38:22 +02007743 set_vim_var_string(VV_OPTION_TYPE, NULL, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02007744 set_vim_var_string(VV_OPTION_COMMAND, NULL, -1);
Bram Moolenaar53744302015-07-17 17:38:22 +02007745}
7746
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007747/*
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02007748 * Add an assert error to v:errors.
7749 */
7750 void
7751assert_error(garray_T *gap)
7752{
7753 struct vimvar *vp = &vimvars[VV_ERRORS];
7754
7755 if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
7756 /* Make sure v:errors is a list. */
7757 set_vim_var_list(VV_ERRORS, list_alloc());
7758 list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
7759}
Bram Moolenaar31988702018-02-13 12:57:42 +01007760/*
7761 * Compare "typ1" and "typ2". Put the result in "typ1".
7762 */
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007763 int
7764typval_compare(
7765 typval_T *typ1, /* first operand */
7766 typval_T *typ2, /* second operand */
7767 exptype_T type, /* operator */
7768 int type_is, /* TRUE for "is" and "isnot" */
Bram Moolenaar31988702018-02-13 12:57:42 +01007769 int ic) /* ignore case */
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007770{
7771 int i;
7772 varnumber_T n1, n2;
7773 char_u *s1, *s2;
7774 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
7775
Bram Moolenaar31988702018-02-13 12:57:42 +01007776 if (type_is && typ1->v_type != typ2->v_type)
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007777 {
Bram Moolenaar31988702018-02-13 12:57:42 +01007778 /* For "is" a different type always means FALSE, for "notis"
7779 * it means TRUE. */
7780 n1 = (type == TYPE_NEQUAL);
7781 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01007782 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
7783 {
7784 if (type_is)
7785 {
7786 n1 = (typ1->v_type == typ2->v_type
7787 && typ1->vval.v_blob == typ2->vval.v_blob);
7788 if (type == TYPE_NEQUAL)
7789 n1 = !n1;
7790 }
7791 else if (typ1->v_type != typ2->v_type
7792 || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
7793 {
7794 if (typ1->v_type != typ2->v_type)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007795 emsg(_("E977: Can only compare Blob with Blob"));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01007796 else
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007797 emsg(_(e_invalblob));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01007798 clear_tv(typ1);
7799 return FAIL;
7800 }
7801 else
7802 {
7803 // Compare two Blobs for being equal or unequal.
7804 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
7805 if (type == TYPE_NEQUAL)
7806 n1 = !n1;
7807 }
7808 }
Bram Moolenaar31988702018-02-13 12:57:42 +01007809 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
7810 {
7811 if (type_is)
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007812 {
Bram Moolenaar31988702018-02-13 12:57:42 +01007813 n1 = (typ1->v_type == typ2->v_type
7814 && typ1->vval.v_list == typ2->vval.v_list);
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007815 if (type == TYPE_NEQUAL)
7816 n1 = !n1;
7817 }
Bram Moolenaar31988702018-02-13 12:57:42 +01007818 else if (typ1->v_type != typ2->v_type
7819 || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007820 {
Bram Moolenaar31988702018-02-13 12:57:42 +01007821 if (typ1->v_type != typ2->v_type)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007822 emsg(_("E691: Can only compare List with List"));
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007823 else
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007824 emsg(_("E692: Invalid operation for List"));
Bram Moolenaar31988702018-02-13 12:57:42 +01007825 clear_tv(typ1);
7826 return FAIL;
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007827 }
7828 else
7829 {
Bram Moolenaar31988702018-02-13 12:57:42 +01007830 /* Compare two Lists for being equal or unequal. */
7831 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
7832 ic, FALSE);
7833 if (type == TYPE_NEQUAL)
7834 n1 = !n1;
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007835 }
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007836 }
Bram Moolenaar31988702018-02-13 12:57:42 +01007837
7838 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
7839 {
7840 if (type_is)
7841 {
7842 n1 = (typ1->v_type == typ2->v_type
7843 && typ1->vval.v_dict == typ2->vval.v_dict);
7844 if (type == TYPE_NEQUAL)
7845 n1 = !n1;
7846 }
7847 else if (typ1->v_type != typ2->v_type
7848 || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
7849 {
7850 if (typ1->v_type != typ2->v_type)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007851 emsg(_("E735: Can only compare Dictionary with Dictionary"));
Bram Moolenaar31988702018-02-13 12:57:42 +01007852 else
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007853 emsg(_("E736: Invalid operation for Dictionary"));
Bram Moolenaar31988702018-02-13 12:57:42 +01007854 clear_tv(typ1);
7855 return FAIL;
7856 }
7857 else
7858 {
7859 /* Compare two Dictionaries for being equal or unequal. */
7860 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
7861 ic, FALSE);
7862 if (type == TYPE_NEQUAL)
7863 n1 = !n1;
7864 }
7865 }
7866
7867 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
7868 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
7869 {
7870 if (type != TYPE_EQUAL && type != TYPE_NEQUAL)
7871 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01007872 emsg(_("E694: Invalid operation for Funcrefs"));
Bram Moolenaar31988702018-02-13 12:57:42 +01007873 clear_tv(typ1);
7874 return FAIL;
7875 }
7876 if ((typ1->v_type == VAR_PARTIAL
7877 && typ1->vval.v_partial == NULL)
7878 || (typ2->v_type == VAR_PARTIAL
7879 && typ2->vval.v_partial == NULL))
7880 /* when a partial is NULL assume not equal */
7881 n1 = FALSE;
7882 else if (type_is)
7883 {
7884 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
7885 /* strings are considered the same if their value is
7886 * the same */
7887 n1 = tv_equal(typ1, typ2, ic, FALSE);
7888 else if (typ1->v_type == VAR_PARTIAL
7889 && typ2->v_type == VAR_PARTIAL)
7890 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
7891 else
7892 n1 = FALSE;
7893 }
7894 else
7895 n1 = tv_equal(typ1, typ2, ic, FALSE);
7896 if (type == TYPE_NEQUAL)
7897 n1 = !n1;
7898 }
7899
7900#ifdef FEAT_FLOAT
7901 /*
7902 * If one of the two variables is a float, compare as a float.
7903 * When using "=~" or "!~", always compare as string.
7904 */
7905 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
7906 && type != TYPE_MATCH && type != TYPE_NOMATCH)
7907 {
7908 float_T f1, f2;
7909
Bram Moolenaar38f08e72019-02-20 22:04:32 +01007910 f1 = tv_get_float(typ1);
7911 f2 = tv_get_float(typ2);
Bram Moolenaar31988702018-02-13 12:57:42 +01007912 n1 = FALSE;
7913 switch (type)
7914 {
7915 case TYPE_EQUAL: n1 = (f1 == f2); break;
7916 case TYPE_NEQUAL: n1 = (f1 != f2); break;
7917 case TYPE_GREATER: n1 = (f1 > f2); break;
7918 case TYPE_GEQUAL: n1 = (f1 >= f2); break;
7919 case TYPE_SMALLER: n1 = (f1 < f2); break;
7920 case TYPE_SEQUAL: n1 = (f1 <= f2); break;
7921 case TYPE_UNKNOWN:
7922 case TYPE_MATCH:
7923 case TYPE_NOMATCH: break; /* avoid gcc warning */
7924 }
7925 }
7926#endif
7927
7928 /*
7929 * If one of the two variables is a number, compare as a number.
7930 * When using "=~" or "!~", always compare as string.
7931 */
7932 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
7933 && type != TYPE_MATCH && type != TYPE_NOMATCH)
7934 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007935 n1 = tv_get_number(typ1);
7936 n2 = tv_get_number(typ2);
Bram Moolenaar31988702018-02-13 12:57:42 +01007937 switch (type)
7938 {
7939 case TYPE_EQUAL: n1 = (n1 == n2); break;
7940 case TYPE_NEQUAL: n1 = (n1 != n2); break;
7941 case TYPE_GREATER: n1 = (n1 > n2); break;
7942 case TYPE_GEQUAL: n1 = (n1 >= n2); break;
7943 case TYPE_SMALLER: n1 = (n1 < n2); break;
7944 case TYPE_SEQUAL: n1 = (n1 <= n2); break;
7945 case TYPE_UNKNOWN:
7946 case TYPE_MATCH:
7947 case TYPE_NOMATCH: break; /* avoid gcc warning */
7948 }
7949 }
7950 else
7951 {
Bram Moolenaard155d7a2018-12-21 16:04:21 +01007952 s1 = tv_get_string_buf(typ1, buf1);
7953 s2 = tv_get_string_buf(typ2, buf2);
Bram Moolenaar31988702018-02-13 12:57:42 +01007954 if (type != TYPE_MATCH && type != TYPE_NOMATCH)
7955 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
7956 else
7957 i = 0;
7958 n1 = FALSE;
7959 switch (type)
7960 {
7961 case TYPE_EQUAL: n1 = (i == 0); break;
7962 case TYPE_NEQUAL: n1 = (i != 0); break;
7963 case TYPE_GREATER: n1 = (i > 0); break;
7964 case TYPE_GEQUAL: n1 = (i >= 0); break;
7965 case TYPE_SMALLER: n1 = (i < 0); break;
7966 case TYPE_SEQUAL: n1 = (i <= 0); break;
7967
7968 case TYPE_MATCH:
7969 case TYPE_NOMATCH:
7970 n1 = pattern_match(s2, s1, ic);
7971 if (type == TYPE_NOMATCH)
7972 n1 = !n1;
7973 break;
7974
7975 case TYPE_UNKNOWN: break; /* avoid gcc warning */
7976 }
7977 }
7978 clear_tv(typ1);
7979 typ1->v_type = VAR_NUMBER;
7980 typ1->vval.v_number = n1;
7981
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007982 return OK;
7983}
7984
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007985 char_u *
Bram Moolenaar6f8d2ac2018-07-25 19:49:45 +02007986typval_tostring(typval_T *arg)
Bram Moolenaarc6f9f732018-02-11 19:06:26 +01007987{
7988 char_u *tofree;
7989 char_u numbuf[NUMBUFLEN];
7990 char_u *ret = NULL;
7991
7992 if (arg == NULL)
7993 return vim_strsave((char_u *)"(does not exist)");
7994 ret = tv2string(arg, &tofree, numbuf, 0);
7995 /* Make a copy if we have a value but it's not in allocated memory. */
7996 if (ret != NULL && tofree == NULL)
7997 ret = vim_strsave(ret);
7998 return ret;
7999}
8000
Bram Moolenaar071d4272004-06-13 20:20:40 +00008001#endif /* FEAT_EVAL */
8002
Bram Moolenaar071d4272004-06-13 20:20:40 +00008003
Bram Moolenaar8c8de832008-06-24 22:58:06 +00008004#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008005
Bram Moolenaar4f974752019-02-17 17:44:42 +01008006#ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +00008007/*
8008 * Functions for ":8" filename modifier: get 8.3 version of a filename.
8009 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00008010
8011/*
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008012 * Get the short path (8.3) for the filename in "fnamep".
8013 * Only works for a valid file name.
8014 * When the path gets longer "fnamep" is changed and the allocated buffer
8015 * is put in "bufp".
8016 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path.
8017 * Returns OK on success, FAIL on failure.
Bram Moolenaar071d4272004-06-13 20:20:40 +00008018 */
8019 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01008020get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008021{
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008022 int l, len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008023 char_u *newbuf;
8024
8025 len = *fnamelen;
Bram Moolenaar6aa2cd42016-02-16 15:06:59 +01008026 l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, len);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008027 if (l > len - 1)
8028 {
8029 /* If that doesn't work (not enough space), then save the string
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008030 * and try again with a new buffer big enough. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00008031 newbuf = vim_strnsave(*fnamep, l);
8032 if (newbuf == NULL)
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008033 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008034
8035 vim_free(*bufp);
8036 *fnamep = *bufp = newbuf;
8037
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008038 /* Really should always succeed, as the buffer is big enough. */
Bram Moolenaar6aa2cd42016-02-16 15:06:59 +01008039 l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, l+1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008040 }
8041
8042 *fnamelen = l;
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008043 return OK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008044}
8045
8046/*
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008047 * Get the short path (8.3) for the filename in "fname". The converted
8048 * path is returned in "bufp".
8049 *
8050 * Some of the directories specified in "fname" may not exist. This function
8051 * will shorten the existing directories at the beginning of the path and then
8052 * append the remaining non-existing path.
8053 *
8054 * fname - Pointer to the filename to shorten. On return, contains the
Bram Moolenaar2c704a72010-06-03 21:17:25 +02008055 * pointer to the shortened pathname
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008056 * bufp - Pointer to an allocated buffer for the filename.
8057 * fnamelen - Length of the filename pointed to by fname
8058 *
8059 * Returns OK on success (or nothing done) and FAIL on failure (out of memory).
Bram Moolenaar071d4272004-06-13 20:20:40 +00008060 */
8061 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01008062shortpath_for_invalid_fname(
8063 char_u **fname,
8064 char_u **bufp,
8065 int *fnamelen)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008066{
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008067 char_u *short_fname, *save_fname, *pbuf_unused;
8068 char_u *endp, *save_endp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008069 char_u ch;
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008070 int old_len, len;
8071 int new_len, sfx_len;
8072 int retval = OK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008073
8074 /* Make a copy */
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008075 old_len = *fnamelen;
8076 save_fname = vim_strnsave(*fname, old_len);
8077 pbuf_unused = NULL;
8078 short_fname = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008079
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008080 endp = save_fname + old_len - 1; /* Find the end of the copy */
8081 save_endp = endp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008082
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008083 /*
8084 * Try shortening the supplied path till it succeeds by removing one
8085 * directory at a time from the tail of the path.
8086 */
8087 len = 0;
8088 for (;;)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008089 {
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008090 /* go back one path-separator */
8091 while (endp > save_fname && !after_pathsep(save_fname, endp + 1))
8092 --endp;
8093 if (endp <= save_fname)
8094 break; /* processed the complete path */
8095
8096 /*
8097 * Replace the path separator with a NUL and try to shorten the
8098 * resulting path.
8099 */
8100 ch = *endp;
8101 *endp = 0;
8102 short_fname = save_fname;
Bram Moolenaarc236c162008-07-13 17:41:49 +00008103 len = (int)STRLEN(short_fname) + 1;
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008104 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL)
8105 {
8106 retval = FAIL;
8107 goto theend;
8108 }
8109 *endp = ch; /* preserve the string */
8110
8111 if (len > 0)
8112 break; /* successfully shortened the path */
8113
8114 /* failed to shorten the path. Skip the path separator */
8115 --endp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008116 }
8117
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008118 if (len > 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008119 {
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008120 /*
8121 * Succeeded in shortening the path. Now concatenate the shortened
8122 * path with the remaining path at the tail.
8123 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00008124
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008125 /* Compute the length of the new path. */
8126 sfx_len = (int)(save_endp - endp) + 1;
8127 new_len = len + sfx_len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008128
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008129 *fnamelen = new_len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008130 vim_free(*bufp);
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008131 if (new_len > old_len)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008132 {
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008133 /* There is not enough space in the currently allocated string,
8134 * copy it to a buffer big enough. */
8135 *fname = *bufp = vim_strnsave(short_fname, new_len);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008136 if (*fname == NULL)
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008137 {
8138 retval = FAIL;
8139 goto theend;
8140 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00008141 }
8142 else
8143 {
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008144 /* Transfer short_fname to the main buffer (it's big enough),
8145 * unless get_short_pathname() did its work in-place. */
8146 *fname = *bufp = save_fname;
8147 if (short_fname != save_fname)
8148 vim_strncpy(save_fname, short_fname, len);
8149 save_fname = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008150 }
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008151
8152 /* concat the not-shortened part of the path */
8153 vim_strncpy(*fname + len, endp, sfx_len);
8154 (*fname)[new_len] = NUL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008155 }
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008156
8157theend:
8158 vim_free(pbuf_unused);
8159 vim_free(save_fname);
8160
8161 return retval;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008162}
8163
8164/*
8165 * Get a pathname for a partial path.
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008166 * Returns OK for success, FAIL for failure.
Bram Moolenaar071d4272004-06-13 20:20:40 +00008167 */
8168 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01008169shortpath_for_partial(
8170 char_u **fnamep,
8171 char_u **bufp,
8172 int *fnamelen)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008173{
8174 int sepcount, len, tflen;
8175 char_u *p;
8176 char_u *pbuf, *tfname;
8177 int hasTilde;
8178
Bram Moolenaar8c8de832008-06-24 22:58:06 +00008179 /* Count up the path separators from the RHS.. so we know which part
8180 * of the path to return. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00008181 sepcount = 0;
Bram Moolenaar91acfff2017-03-12 19:22:36 +01008182 for (p = *fnamep; p < *fnamep + *fnamelen; MB_PTR_ADV(p))
Bram Moolenaar071d4272004-06-13 20:20:40 +00008183 if (vim_ispathsep(*p))
8184 ++sepcount;
8185
8186 /* Need full path first (use expand_env() to remove a "~/") */
8187 hasTilde = (**fnamep == '~');
8188 if (hasTilde)
8189 pbuf = tfname = expand_env_save(*fnamep);
8190 else
8191 pbuf = tfname = FullName_save(*fnamep, FALSE);
8192
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00008193 len = tflen = (int)STRLEN(tfname);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008194
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008195 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL)
8196 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008197
8198 if (len == 0)
8199 {
8200 /* Don't have a valid filename, so shorten the rest of the
8201 * path if we can. This CAN give us invalid 8.3 filenames, but
8202 * there's not a lot of point in guessing what it might be.
8203 */
8204 len = tflen;
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008205 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL)
8206 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008207 }
8208
8209 /* Count the paths backward to find the beginning of the desired string. */
8210 for (p = tfname + len - 1; p >= tfname; --p)
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00008211 {
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00008212 if (has_mbyte)
8213 p -= mb_head_off(tfname, p);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008214 if (vim_ispathsep(*p))
8215 {
8216 if (sepcount == 0 || (hasTilde && sepcount == 1))
8217 break;
8218 else
8219 sepcount --;
8220 }
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00008221 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00008222 if (hasTilde)
8223 {
8224 --p;
8225 if (p >= tfname)
8226 *p = '~';
8227 else
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008228 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008229 }
8230 else
8231 ++p;
8232
8233 /* Copy in the string - p indexes into tfname - allocated at pbuf */
8234 vim_free(*bufp);
8235 *fnamelen = (int)STRLEN(p);
8236 *bufp = pbuf;
8237 *fnamep = p;
8238
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008239 return OK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008240}
Bram Moolenaar4f974752019-02-17 17:44:42 +01008241#endif // MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +00008242
8243/*
8244 * Adjust a filename, according to a string of modifiers.
8245 * *fnamep must be NUL terminated when called. When returning, the length is
8246 * determined by *fnamelen.
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008247 * Returns VALID_ flags or -1 for failure.
Bram Moolenaar071d4272004-06-13 20:20:40 +00008248 * When there is an error, *fnamep is set to NULL.
8249 */
8250 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01008251modify_fname(
Bram Moolenaar00136dc2018-07-25 21:19:13 +02008252 char_u *src, // string with modifiers
8253 int tilde_file, // "~" is a file name, not $HOME
8254 int *usedlen, // characters after src that are used
8255 char_u **fnamep, // file name so far
8256 char_u **bufp, // buffer for allocated file name or NULL
8257 int *fnamelen) // length of fnamep
Bram Moolenaar071d4272004-06-13 20:20:40 +00008258{
8259 int valid = 0;
8260 char_u *tail;
8261 char_u *s, *p, *pbuf;
8262 char_u dirname[MAXPATHL];
8263 int c;
8264 int has_fullname = 0;
Bram Moolenaar4f974752019-02-17 17:44:42 +01008265#ifdef MSWIN
Bram Moolenaardc935552011-08-17 15:23:23 +02008266 char_u *fname_start = *fnamep;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008267 int has_shortname = 0;
8268#endif
8269
8270repeat:
8271 /* ":p" - full path/file_name */
8272 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
8273 {
8274 has_fullname = 1;
8275
8276 valid |= VALID_PATH;
8277 *usedlen += 2;
8278
8279 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */
8280 if ((*fnamep)[0] == '~'
8281#if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME))
8282 && ((*fnamep)[1] == '/'
8283# ifdef BACKSLASH_IN_FILENAME
8284 || (*fnamep)[1] == '\\'
8285# endif
8286 || (*fnamep)[1] == NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008287#endif
Bram Moolenaar00136dc2018-07-25 21:19:13 +02008288 && !(tilde_file && (*fnamep)[1] == NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008289 )
8290 {
8291 *fnamep = expand_env_save(*fnamep);
8292 vim_free(*bufp); /* free any allocated file name */
8293 *bufp = *fnamep;
8294 if (*fnamep == NULL)
8295 return -1;
8296 }
8297
8298 /* When "/." or "/.." is used: force expansion to get rid of it. */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01008299 for (p = *fnamep; *p != NUL; MB_PTR_ADV(p))
Bram Moolenaar071d4272004-06-13 20:20:40 +00008300 {
8301 if (vim_ispathsep(*p)
8302 && p[1] == '.'
8303 && (p[2] == NUL
8304 || vim_ispathsep(p[2])
8305 || (p[2] == '.'
8306 && (p[3] == NUL || vim_ispathsep(p[3])))))
8307 break;
8308 }
8309
8310 /* FullName_save() is slow, don't use it when not needed. */
8311 if (*p != NUL || !vim_isAbsName(*fnamep))
8312 {
8313 *fnamep = FullName_save(*fnamep, *p != NUL);
8314 vim_free(*bufp); /* free any allocated file name */
8315 *bufp = *fnamep;
8316 if (*fnamep == NULL)
8317 return -1;
8318 }
8319
Bram Moolenaar4f974752019-02-17 17:44:42 +01008320#ifdef MSWIN
Bram Moolenaar9158f9e2012-06-20 14:02:27 +02008321# if _WIN32_WINNT >= 0x0500
8322 if (vim_strchr(*fnamep, '~') != NULL)
8323 {
Bram Moolenaar2d04a912019-03-30 20:04:08 +01008324 // Expand 8.3 filename to full path. Needed to make sure the same
8325 // file does not have two different names.
8326 // Note: problem does not occur if _WIN32_WINNT < 0x0500.
8327 WCHAR *wfname = enc_to_utf16(*fnamep, NULL);
8328 WCHAR buf[_MAX_PATH];
8329
8330 if (wfname != NULL)
Bram Moolenaar9158f9e2012-06-20 14:02:27 +02008331 {
Bram Moolenaar2d04a912019-03-30 20:04:08 +01008332 if (GetLongPathNameW(wfname, buf, _MAX_PATH))
Bram Moolenaar9158f9e2012-06-20 14:02:27 +02008333 {
Bram Moolenaar2d04a912019-03-30 20:04:08 +01008334 char_u *p = utf16_to_enc(buf, NULL);
8335
8336 if (p != NULL)
8337 {
8338 vim_free(*bufp); // free any allocated file name
8339 *bufp = *fnamep = p;
8340 }
Bram Moolenaar9158f9e2012-06-20 14:02:27 +02008341 }
Bram Moolenaar2d04a912019-03-30 20:04:08 +01008342 vim_free(wfname);
Bram Moolenaar9158f9e2012-06-20 14:02:27 +02008343 }
8344 }
8345# endif
8346#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00008347 /* Append a path separator to a directory. */
8348 if (mch_isdir(*fnamep))
8349 {
8350 /* Make room for one or two extra characters. */
8351 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
8352 vim_free(*bufp); /* free any allocated file name */
8353 *bufp = *fnamep;
8354 if (*fnamep == NULL)
8355 return -1;
8356 add_pathsep(*fnamep);
8357 }
8358 }
8359
8360 /* ":." - path relative to the current directory */
8361 /* ":~" - path relative to the home directory */
8362 /* ":8" - shortname path - postponed till after */
8363 while (src[*usedlen] == ':'
8364 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8'))
8365 {
8366 *usedlen += 2;
8367 if (c == '8')
8368 {
Bram Moolenaar4f974752019-02-17 17:44:42 +01008369#ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +00008370 has_shortname = 1; /* Postpone this. */
8371#endif
8372 continue;
8373 }
8374 pbuf = NULL;
8375 /* Need full path first (use expand_env() to remove a "~/") */
8376 if (!has_fullname)
8377 {
8378 if (c == '.' && **fnamep == '~')
8379 p = pbuf = expand_env_save(*fnamep);
8380 else
8381 p = pbuf = FullName_save(*fnamep, FALSE);
8382 }
8383 else
8384 p = *fnamep;
8385
8386 has_fullname = 0;
8387
8388 if (p != NULL)
8389 {
8390 if (c == '.')
8391 {
8392 mch_dirname(dirname, MAXPATHL);
8393 s = shorten_fname(p, dirname);
8394 if (s != NULL)
8395 {
8396 *fnamep = s;
8397 if (pbuf != NULL)
8398 {
8399 vim_free(*bufp); /* free any allocated file name */
8400 *bufp = pbuf;
8401 pbuf = NULL;
8402 }
8403 }
8404 }
8405 else
8406 {
8407 home_replace(NULL, p, dirname, MAXPATHL, TRUE);
8408 /* Only replace it when it starts with '~' */
8409 if (*dirname == '~')
8410 {
8411 s = vim_strsave(dirname);
8412 if (s != NULL)
8413 {
8414 *fnamep = s;
8415 vim_free(*bufp);
8416 *bufp = s;
8417 }
8418 }
8419 }
8420 vim_free(pbuf);
8421 }
8422 }
8423
8424 tail = gettail(*fnamep);
8425 *fnamelen = (int)STRLEN(*fnamep);
8426
8427 /* ":h" - head, remove "/file_name", can be repeated */
8428 /* Don't remove the first "/" or "c:\" */
8429 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
8430 {
8431 valid |= VALID_HEAD;
8432 *usedlen += 2;
8433 s = get_past_head(*fnamep);
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00008434 while (tail > s && after_pathsep(s, tail))
Bram Moolenaar91acfff2017-03-12 19:22:36 +01008435 MB_PTR_BACK(*fnamep, tail);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008436 *fnamelen = (int)(tail - *fnamep);
8437#ifdef VMS
8438 if (*fnamelen > 0)
8439 *fnamelen += 1; /* the path separator is part of the path */
8440#endif
Bram Moolenaar5461cfe2007-09-25 18:40:14 +00008441 if (*fnamelen == 0)
8442 {
8443 /* Result is empty. Turn it into "." to make ":cd %:h" work. */
8444 p = vim_strsave((char_u *)".");
8445 if (p == NULL)
8446 return -1;
8447 vim_free(*bufp);
8448 *bufp = *fnamep = tail = p;
8449 *fnamelen = 1;
8450 }
8451 else
8452 {
8453 while (tail > s && !after_pathsep(s, tail))
Bram Moolenaar91acfff2017-03-12 19:22:36 +01008454 MB_PTR_BACK(*fnamep, tail);
Bram Moolenaar5461cfe2007-09-25 18:40:14 +00008455 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00008456 }
8457
8458 /* ":8" - shortname */
8459 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8')
8460 {
8461 *usedlen += 2;
Bram Moolenaar4f974752019-02-17 17:44:42 +01008462#ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +00008463 has_shortname = 1;
8464#endif
8465 }
8466
Bram Moolenaar4f974752019-02-17 17:44:42 +01008467#ifdef MSWIN
Bram Moolenaardc935552011-08-17 15:23:23 +02008468 /*
8469 * Handle ":8" after we have done 'heads' and before we do 'tails'.
Bram Moolenaar071d4272004-06-13 20:20:40 +00008470 */
8471 if (has_shortname)
8472 {
Bram Moolenaardc935552011-08-17 15:23:23 +02008473 /* Copy the string if it is shortened by :h and when it wasn't copied
8474 * yet, because we are going to change it in place. Avoids changing
8475 * the buffer name for "%:8". */
8476 if (*fnamelen < (int)STRLEN(*fnamep) || *fnamep == fname_start)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008477 {
8478 p = vim_strnsave(*fnamep, *fnamelen);
Bram Moolenaardc935552011-08-17 15:23:23 +02008479 if (p == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008480 return -1;
8481 vim_free(*bufp);
8482 *bufp = *fnamep = p;
8483 }
8484
8485 /* Split into two implementations - makes it easier. First is where
Bram Moolenaardc935552011-08-17 15:23:23 +02008486 * there isn't a full name already, second is where there is. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00008487 if (!has_fullname && !vim_isAbsName(*fnamep))
8488 {
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008489 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008490 return -1;
8491 }
8492 else
8493 {
Bram Moolenaardc935552011-08-17 15:23:23 +02008494 int l = *fnamelen;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008495
Bram Moolenaardc935552011-08-17 15:23:23 +02008496 /* Simple case, already have the full-name.
Bram Moolenaar071d4272004-06-13 20:20:40 +00008497 * Nearly always shorter, so try first time. */
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008498 if (get_short_pathname(fnamep, bufp, &l) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008499 return -1;
8500
8501 if (l == 0)
8502 {
Bram Moolenaardc935552011-08-17 15:23:23 +02008503 /* Couldn't find the filename, search the paths. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00008504 l = *fnamelen;
Bram Moolenaarbcebfb62008-05-29 19:47:13 +00008505 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008506 return -1;
8507 }
8508 *fnamelen = l;
8509 }
8510 }
Bram Moolenaar4f974752019-02-17 17:44:42 +01008511#endif // MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +00008512
8513 /* ":t" - tail, just the basename */
8514 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
8515 {
8516 *usedlen += 2;
8517 *fnamelen -= (int)(tail - *fnamep);
8518 *fnamep = tail;
8519 }
8520
8521 /* ":e" - extension, can be repeated */
8522 /* ":r" - root, without extension, can be repeated */
8523 while (src[*usedlen] == ':'
8524 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
8525 {
8526 /* find a '.' in the tail:
8527 * - for second :e: before the current fname
8528 * - otherwise: The last '.'
8529 */
8530 if (src[*usedlen + 1] == 'e' && *fnamep > tail)
8531 s = *fnamep - 2;
8532 else
8533 s = *fnamep + *fnamelen - 1;
8534 for ( ; s > tail; --s)
8535 if (s[0] == '.')
8536 break;
8537 if (src[*usedlen + 1] == 'e') /* :e */
8538 {
8539 if (s > tail)
8540 {
8541 *fnamelen += (int)(*fnamep - (s + 1));
8542 *fnamep = s + 1;
8543#ifdef VMS
8544 /* cut version from the extension */
8545 s = *fnamep + *fnamelen - 1;
8546 for ( ; s > *fnamep; --s)
8547 if (s[0] == ';')
8548 break;
8549 if (s > *fnamep)
8550 *fnamelen = s - *fnamep;
8551#endif
8552 }
8553 else if (*fnamep <= tail)
8554 *fnamelen = 0;
8555 }
8556 else /* :r */
8557 {
8558 if (s > tail) /* remove one extension */
8559 *fnamelen = (int)(s - *fnamep);
8560 }
8561 *usedlen += 2;
8562 }
8563
8564 /* ":s?pat?foo?" - substitute */
8565 /* ":gs?pat?foo?" - global substitute */
8566 if (src[*usedlen] == ':'
8567 && (src[*usedlen + 1] == 's'
8568 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
8569 {
8570 char_u *str;
8571 char_u *pat;
8572 char_u *sub;
8573 int sep;
8574 char_u *flags;
8575 int didit = FALSE;
8576
8577 flags = (char_u *)"";
8578 s = src + *usedlen + 2;
8579 if (src[*usedlen + 1] == 'g')
8580 {
8581 flags = (char_u *)"g";
8582 ++s;
8583 }
8584
8585 sep = *s++;
8586 if (sep)
8587 {
8588 /* find end of pattern */
8589 p = vim_strchr(s, sep);
8590 if (p != NULL)
8591 {
8592 pat = vim_strnsave(s, (int)(p - s));
8593 if (pat != NULL)
8594 {
8595 s = p + 1;
8596 /* find end of substitution */
8597 p = vim_strchr(s, sep);
8598 if (p != NULL)
8599 {
8600 sub = vim_strnsave(s, (int)(p - s));
8601 str = vim_strnsave(*fnamep, *fnamelen);
8602 if (sub != NULL && str != NULL)
8603 {
8604 *usedlen = (int)(p + 1 - src);
Bram Moolenaar72ab7292016-07-19 19:10:51 +02008605 s = do_string_sub(str, pat, sub, NULL, flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008606 if (s != NULL)
8607 {
8608 *fnamep = s;
8609 *fnamelen = (int)STRLEN(s);
8610 vim_free(*bufp);
8611 *bufp = s;
8612 didit = TRUE;
8613 }
8614 }
8615 vim_free(sub);
8616 vim_free(str);
8617 }
8618 vim_free(pat);
8619 }
8620 }
8621 /* after using ":s", repeat all the modifiers */
8622 if (didit)
8623 goto repeat;
8624 }
8625 }
8626
Bram Moolenaar26df0922014-02-23 23:39:13 +01008627 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S')
8628 {
Bram Moolenaar5ca84ce2016-03-23 22:28:25 +01008629 /* vim_strsave_shellescape() needs a NUL terminated string. */
Bram Moolenaard4caf5c2016-03-24 19:14:35 +01008630 c = (*fnamep)[*fnamelen];
Bram Moolenaar52c6eaf2016-03-25 18:42:46 +01008631 if (c != NUL)
8632 (*fnamep)[*fnamelen] = NUL;
Bram Moolenaar26df0922014-02-23 23:39:13 +01008633 p = vim_strsave_shellescape(*fnamep, FALSE, FALSE);
Bram Moolenaar52c6eaf2016-03-25 18:42:46 +01008634 if (c != NUL)
8635 (*fnamep)[*fnamelen] = c;
Bram Moolenaar26df0922014-02-23 23:39:13 +01008636 if (p == NULL)
8637 return -1;
8638 vim_free(*bufp);
8639 *bufp = *fnamep = p;
8640 *fnamelen = (int)STRLEN(p);
8641 *usedlen += 2;
8642 }
8643
Bram Moolenaar071d4272004-06-13 20:20:40 +00008644 return valid;
8645}
8646
8647/*
8648 * Perform a substitution on "str" with pattern "pat" and substitute "sub".
Bram Moolenaar72ab7292016-07-19 19:10:51 +02008649 * When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL.
Bram Moolenaar071d4272004-06-13 20:20:40 +00008650 * "flags" can be "g" to do a global substitute.
8651 * Returns an allocated string, NULL for error.
8652 */
8653 char_u *
Bram Moolenaar7454a062016-01-30 15:14:10 +01008654do_string_sub(
8655 char_u *str,
8656 char_u *pat,
8657 char_u *sub,
Bram Moolenaar72ab7292016-07-19 19:10:51 +02008658 typval_T *expr,
Bram Moolenaar7454a062016-01-30 15:14:10 +01008659 char_u *flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008660{
8661 int sublen;
8662 regmatch_T regmatch;
8663 int i;
8664 int do_all;
8665 char_u *tail;
Bram Moolenaare90c8532014-11-05 16:03:44 +01008666 char_u *end;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008667 garray_T ga;
8668 char_u *ret;
8669 char_u *save_cpo;
Bram Moolenaar8af26912014-01-23 20:09:34 +01008670 char_u *zero_width = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008671
8672 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
8673 save_cpo = p_cpo;
Bram Moolenaar9c24ccc2008-07-14 21:05:15 +00008674 p_cpo = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008675
8676 ga_init2(&ga, 1, 200);
8677
8678 do_all = (flags[0] == 'g');
8679
8680 regmatch.rm_ic = p_ic;
8681 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
8682 if (regmatch.regprog != NULL)
8683 {
8684 tail = str;
Bram Moolenaare90c8532014-11-05 16:03:44 +01008685 end = str + STRLEN(str);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008686 while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
8687 {
Bram Moolenaar8af26912014-01-23 20:09:34 +01008688 /* Skip empty match except for first match. */
8689 if (regmatch.startp[0] == regmatch.endp[0])
8690 {
8691 if (zero_width == regmatch.startp[0])
8692 {
8693 /* avoid getting stuck on a match with an empty string */
Bram Moolenaar8e7048c2014-06-12 18:39:22 +02008694 i = MB_PTR2LEN(tail);
8695 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail,
8696 (size_t)i);
8697 ga.ga_len += i;
8698 tail += i;
Bram Moolenaar8af26912014-01-23 20:09:34 +01008699 continue;
8700 }
8701 zero_width = regmatch.startp[0];
8702 }
8703
Bram Moolenaar071d4272004-06-13 20:20:40 +00008704 /*
8705 * Get some space for a temporary buffer to do the substitution
8706 * into. It will contain:
8707 * - The text up to where the match is.
8708 * - The substituted text.
8709 * - The text after the match.
8710 */
Bram Moolenaar72ab7292016-07-19 19:10:51 +02008711 sublen = vim_regsub(&regmatch, sub, expr, tail, FALSE, TRUE, FALSE);
Bram Moolenaare90c8532014-11-05 16:03:44 +01008712 if (ga_grow(&ga, (int)((end - tail) + sublen -
Bram Moolenaar071d4272004-06-13 20:20:40 +00008713 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
8714 {
8715 ga_clear(&ga);
8716 break;
8717 }
8718
8719 /* copy the text up to where the match is */
8720 i = (int)(regmatch.startp[0] - tail);
8721 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
8722 /* add the substituted text */
Bram Moolenaar72ab7292016-07-19 19:10:51 +02008723 (void)vim_regsub(&regmatch, sub, expr, (char_u *)ga.ga_data
Bram Moolenaar071d4272004-06-13 20:20:40 +00008724 + ga.ga_len + i, TRUE, TRUE, FALSE);
8725 ga.ga_len += i + sublen - 1;
Bram Moolenaarceb84af2013-09-29 21:11:05 +02008726 tail = regmatch.endp[0];
8727 if (*tail == NUL)
8728 break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00008729 if (!do_all)
8730 break;
8731 }
8732
8733 if (ga.ga_data != NULL)
8734 STRCPY((char *)ga.ga_data + ga.ga_len, tail);
8735
Bram Moolenaar473de612013-06-08 18:19:48 +02008736 vim_regfree(regmatch.regprog);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008737 }
8738
8739 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
8740 ga_clear(&ga);
Bram Moolenaar9c24ccc2008-07-14 21:05:15 +00008741 if (p_cpo == empty_option)
8742 p_cpo = save_cpo;
8743 else
Bram Moolenaar72ab7292016-07-19 19:10:51 +02008744 /* Darn, evaluating {sub} expression or {expr} changed the value. */
Bram Moolenaar9c24ccc2008-07-14 21:05:15 +00008745 free_string_option(save_cpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00008746
8747 return ret;
8748}
8749
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008750 static int
8751filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
8752{
8753 typval_T rettv;
8754 typval_T argv[3];
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008755 int retval = FAIL;
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008756
8757 copy_tv(tv, &vimvars[VV_VAL].vv_tv);
8758 argv[0] = vimvars[VV_KEY].vv_tv;
8759 argv[1] = vimvars[VV_VAL].vv_tv;
Bram Moolenaar48570482017-10-30 21:48:41 +01008760 if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL)
8761 goto theend;
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008762 if (map)
8763 {
8764 /* map(): replace the list item value */
8765 clear_tv(tv);
8766 rettv.v_lock = 0;
8767 *tv = rettv;
8768 }
8769 else
8770 {
8771 int error = FALSE;
8772
8773 /* filter(): when expr is zero remove the item */
Bram Moolenaard155d7a2018-12-21 16:04:21 +01008774 *remp = (tv_get_number_chk(&rettv, &error) == 0);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008775 clear_tv(&rettv);
8776 /* On type error, nothing has been removed; return FAIL to stop the
Bram Moolenaard155d7a2018-12-21 16:04:21 +01008777 * loop. The error message was given by tv_get_number_chk(). */
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008778 if (error)
8779 goto theend;
8780 }
8781 retval = OK;
8782theend:
8783 clear_tv(&vimvars[VV_VAL].vv_tv);
8784 return retval;
8785}
8786
8787
8788/*
8789 * Implementation of map() and filter().
8790 */
8791 void
8792filter_map(typval_T *argvars, typval_T *rettv, int map)
8793{
8794 typval_T *expr;
8795 listitem_T *li, *nli;
8796 list_T *l = NULL;
8797 dictitem_T *di;
8798 hashtab_T *ht;
8799 hashitem_T *hi;
8800 dict_T *d = NULL;
8801 typval_T save_val;
8802 typval_T save_key;
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01008803 blob_T *b = NULL;
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008804 int rem;
8805 int todo;
8806 char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
8807 char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
8808 : N_("filter() argument"));
8809 int save_did_emsg;
8810 int idx = 0;
8811
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01008812 if (argvars[0].v_type == VAR_BLOB)
8813 {
8814 if ((b = argvars[0].vval.v_blob) == NULL)
8815 return;
8816 }
8817 else if (argvars[0].v_type == VAR_LIST)
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008818 {
8819 if ((l = argvars[0].vval.v_list) == NULL
Bram Moolenaar05c00c02019-02-11 22:00:11 +01008820 || (!map && var_check_lock(l->lv_lock, arg_errmsg, TRUE)))
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008821 return;
8822 }
8823 else if (argvars[0].v_type == VAR_DICT)
8824 {
8825 if ((d = argvars[0].vval.v_dict) == NULL
Bram Moolenaar05c00c02019-02-11 22:00:11 +01008826 || (!map && var_check_lock(d->dv_lock, arg_errmsg, TRUE)))
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008827 return;
8828 }
8829 else
8830 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01008831 semsg(_(e_listdictarg), ermsg);
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008832 return;
8833 }
8834
8835 expr = &argvars[1];
8836 /* On type errors, the preceding call has already displayed an error
8837 * message. Avoid a misleading error message for an empty string that
8838 * was not passed as argument. */
8839 if (expr->v_type != VAR_UNKNOWN)
8840 {
8841 prepare_vimvar(VV_VAL, &save_val);
8842
8843 /* We reset "did_emsg" to be able to detect whether an error
8844 * occurred during evaluation of the expression. */
8845 save_did_emsg = did_emsg;
8846 did_emsg = FALSE;
8847
8848 prepare_vimvar(VV_KEY, &save_key);
8849 if (argvars[0].v_type == VAR_DICT)
8850 {
8851 vimvars[VV_KEY].vv_type = VAR_STRING;
8852
8853 ht = &d->dv_hashtab;
8854 hash_lock(ht);
8855 todo = (int)ht->ht_used;
8856 for (hi = ht->ht_array; todo > 0; ++hi)
8857 {
8858 if (!HASHITEM_EMPTY(hi))
8859 {
8860 int r;
8861
8862 --todo;
8863 di = HI2DI(hi);
Bram Moolenaar05c00c02019-02-11 22:00:11 +01008864 if (map && (var_check_lock(di->di_tv.v_lock,
8865 arg_errmsg, TRUE)
8866 || var_check_ro(di->di_flags,
8867 arg_errmsg, TRUE)))
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008868 break;
8869 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
8870 r = filter_map_one(&di->di_tv, expr, map, &rem);
8871 clear_tv(&vimvars[VV_KEY].vv_tv);
8872 if (r == FAIL || did_emsg)
8873 break;
8874 if (!map && rem)
8875 {
8876 if (var_check_fixed(di->di_flags, arg_errmsg, TRUE)
8877 || var_check_ro(di->di_flags, arg_errmsg, TRUE))
8878 break;
8879 dictitem_remove(d, di);
8880 }
8881 }
8882 }
8883 hash_unlock(ht);
8884 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01008885 else if (argvars[0].v_type == VAR_BLOB)
8886 {
8887 int i;
8888 typval_T tv;
8889
8890 vimvars[VV_KEY].vv_type = VAR_NUMBER;
8891 for (i = 0; i < b->bv_ga.ga_len; i++)
8892 {
8893 tv.v_type = VAR_NUMBER;
8894 tv.vval.v_number = blob_get(b, i);
8895 vimvars[VV_KEY].vv_nr = idx;
8896 if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg)
8897 break;
8898 if (tv.v_type != VAR_NUMBER)
8899 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01008900 emsg(_(e_invalblob));
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01008901 return;
8902 }
8903 tv.v_type = VAR_NUMBER;
8904 blob_set(b, i, tv.vval.v_number);
8905 if (!map && rem)
8906 {
8907 char_u *p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
8908
8909 mch_memmove(p + idx, p + i + 1,
8910 (size_t)b->bv_ga.ga_len - i - 1);
8911 --b->bv_ga.ga_len;
8912 --i;
8913 }
8914 }
8915 }
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008916 else
8917 {
Bram Moolenaarce9d50d2019-01-14 22:22:29 +01008918 // argvars[0].v_type == VAR_LIST
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008919 vimvars[VV_KEY].vv_type = VAR_NUMBER;
8920
8921 for (li = l->lv_first; li != NULL; li = nli)
8922 {
Bram Moolenaar05c00c02019-02-11 22:00:11 +01008923 if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE))
Bram Moolenaar73dad1e2016-07-17 22:13:49 +02008924 break;
8925 nli = li->li_next;
8926 vimvars[VV_KEY].vv_nr = idx;
8927 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
8928 || did_emsg)
8929 break;
8930 if (!map && rem)
8931 listitem_remove(l, li);
8932 ++idx;
8933 }
8934 }
8935
8936 restore_vimvar(VV_KEY, &save_key);
8937 restore_vimvar(VV_VAL, &save_val);
8938
8939 did_emsg |= save_did_emsg;
8940 }
8941
8942 copy_tv(&argvars[0], rettv);
8943}
8944
Bram Moolenaar071d4272004-06-13 20:20:40 +00008945#endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */