blob: abda5f050438f896dc885ad5d4c6aaf90afab003 [file] [log] [blame]
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001/* vi:set ts=8 sts=4 sw=4 noet:
2 *
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 * typval.c: functions that deal with a typval
12 */
13
14#include "vim.h"
15
16#if defined(FEAT_EVAL) || defined(PROTO)
17
18/*
19 * Allocate memory for a variable type-value, and make it empty (0 or NULL
20 * value).
21 */
22 typval_T *
23alloc_tv(void)
24{
25 return ALLOC_CLEAR_ONE(typval_T);
26}
27
28/*
29 * Allocate memory for a variable type-value, and assign a string to it.
30 * The string "s" must have been allocated, it is consumed.
31 * Return NULL for out of memory, the variable otherwise.
32 */
33 typval_T *
34alloc_string_tv(char_u *s)
35{
36 typval_T *rettv;
37
38 rettv = alloc_tv();
39 if (rettv != NULL)
40 {
41 rettv->v_type = VAR_STRING;
42 rettv->vval.v_string = s;
43 }
44 else
45 vim_free(s);
46 return rettv;
47}
48
49/*
50 * Free the memory for a variable type-value.
51 */
52 void
53free_tv(typval_T *varp)
54{
55 if (varp != NULL)
56 {
57 switch (varp->v_type)
58 {
59 case VAR_FUNC:
60 func_unref(varp->vval.v_string);
61 // FALLTHROUGH
62 case VAR_STRING:
63 vim_free(varp->vval.v_string);
64 break;
65 case VAR_PARTIAL:
66 partial_unref(varp->vval.v_partial);
67 break;
68 case VAR_BLOB:
69 blob_unref(varp->vval.v_blob);
70 break;
71 case VAR_LIST:
72 list_unref(varp->vval.v_list);
73 break;
74 case VAR_DICT:
75 dict_unref(varp->vval.v_dict);
76 break;
77 case VAR_JOB:
78#ifdef FEAT_JOB_CHANNEL
79 job_unref(varp->vval.v_job);
80 break;
81#endif
82 case VAR_CHANNEL:
83#ifdef FEAT_JOB_CHANNEL
84 channel_unref(varp->vval.v_channel);
85 break;
86#endif
87 case VAR_NUMBER:
88 case VAR_FLOAT:
89 case VAR_ANY:
90 case VAR_UNKNOWN:
91 case VAR_VOID:
92 case VAR_BOOL:
93 case VAR_SPECIAL:
Bram Moolenaarf18332f2021-05-07 17:55:55 +020094 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +020095 break;
96 }
97 vim_free(varp);
98 }
99}
100
101/*
102 * Free the memory for a variable value and set the value to NULL or 0.
103 */
104 void
105clear_tv(typval_T *varp)
106{
107 if (varp != NULL)
108 {
109 switch (varp->v_type)
110 {
111 case VAR_FUNC:
112 func_unref(varp->vval.v_string);
113 // FALLTHROUGH
114 case VAR_STRING:
115 VIM_CLEAR(varp->vval.v_string);
116 break;
117 case VAR_PARTIAL:
118 partial_unref(varp->vval.v_partial);
119 varp->vval.v_partial = NULL;
120 break;
121 case VAR_BLOB:
122 blob_unref(varp->vval.v_blob);
123 varp->vval.v_blob = NULL;
124 break;
125 case VAR_LIST:
126 list_unref(varp->vval.v_list);
127 varp->vval.v_list = NULL;
128 break;
129 case VAR_DICT:
130 dict_unref(varp->vval.v_dict);
131 varp->vval.v_dict = NULL;
132 break;
133 case VAR_NUMBER:
134 case VAR_BOOL:
135 case VAR_SPECIAL:
136 varp->vval.v_number = 0;
137 break;
138 case VAR_FLOAT:
139#ifdef FEAT_FLOAT
140 varp->vval.v_float = 0.0;
141 break;
142#endif
143 case VAR_JOB:
144#ifdef FEAT_JOB_CHANNEL
145 job_unref(varp->vval.v_job);
146 varp->vval.v_job = NULL;
147#endif
148 break;
149 case VAR_CHANNEL:
150#ifdef FEAT_JOB_CHANNEL
151 channel_unref(varp->vval.v_channel);
152 varp->vval.v_channel = NULL;
153#endif
Bram Moolenaar24f72092021-05-07 20:43:54 +0200154 break;
155 case VAR_INSTR:
156 VIM_CLEAR(varp->vval.v_instr);
157 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200158 case VAR_UNKNOWN:
159 case VAR_ANY:
160 case VAR_VOID:
161 break;
162 }
163 varp->v_lock = 0;
164 }
165}
166
167/*
168 * Set the value of a variable to NULL without freeing items.
169 */
170 void
171init_tv(typval_T *varp)
172{
173 if (varp != NULL)
174 CLEAR_POINTER(varp);
175}
176
Bram Moolenaar36967b32020-08-17 21:41:02 +0200177 static varnumber_T
178tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200179{
180 varnumber_T n = 0L;
181
182 switch (varp->v_type)
183 {
184 case VAR_NUMBER:
Bram Moolenaarbade44e2020-09-26 22:39:24 +0200185 if (in_vim9script() && want_bool && varp->vval.v_number != 0
Bram Moolenaard70840e2020-08-22 15:06:35 +0200186 && varp->vval.v_number != 1)
187 {
188 semsg(_(e_using_number_as_bool_nr), varp->vval.v_number);
189 break;
190 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200191 return varp->vval.v_number;
192 case VAR_FLOAT:
193#ifdef FEAT_FLOAT
194 emsg(_("E805: Using a Float as a Number"));
195 break;
196#endif
197 case VAR_FUNC:
198 case VAR_PARTIAL:
199 emsg(_("E703: Using a Funcref as a Number"));
200 break;
201 case VAR_STRING:
Bram Moolenaar56acb092020-08-16 14:48:19 +0200202 if (in_vim9script())
203 {
Bram Moolenaarea2d4072020-11-12 12:08:51 +0100204 emsg_using_string_as(varp, !want_bool);
Bram Moolenaar56acb092020-08-16 14:48:19 +0200205 break;
206 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200207 if (varp->vval.v_string != NULL)
208 vim_str2nr(varp->vval.v_string, NULL, NULL,
209 STR2NR_ALL, &n, NULL, 0, FALSE);
210 return n;
211 case VAR_LIST:
212 emsg(_("E745: Using a List as a Number"));
213 break;
214 case VAR_DICT:
215 emsg(_("E728: Using a Dictionary as a Number"));
216 break;
217 case VAR_BOOL:
218 case VAR_SPECIAL:
Bram Moolenaar36967b32020-08-17 21:41:02 +0200219 if (!want_bool && in_vim9script())
Bram Moolenaar56acb092020-08-16 14:48:19 +0200220 {
Bram Moolenaard92cc132020-11-18 17:17:15 +0100221 if (varp->v_type == VAR_BOOL)
222 emsg(_(e_using_bool_as_number));
223 else
224 emsg(_("E611: Using a Special as a Number"));
Bram Moolenaar56acb092020-08-16 14:48:19 +0200225 break;
226 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200227 return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
228 case VAR_JOB:
229#ifdef FEAT_JOB_CHANNEL
230 emsg(_("E910: Using a Job as a Number"));
231 break;
232#endif
233 case VAR_CHANNEL:
234#ifdef FEAT_JOB_CHANNEL
235 emsg(_("E913: Using a Channel as a Number"));
236 break;
237#endif
238 case VAR_BLOB:
239 emsg(_("E974: Using a Blob as a Number"));
240 break;
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200241 case VAR_VOID:
242 emsg(_(e_cannot_use_void_value));
243 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200244 case VAR_UNKNOWN:
245 case VAR_ANY:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200246 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200247 internal_error_no_abort("tv_get_number(UNKNOWN)");
248 break;
249 }
250 if (denote == NULL) // useful for values that must be unsigned
251 n = -1;
252 else
253 *denote = TRUE;
254 return n;
255}
256
Bram Moolenaar36967b32020-08-17 21:41:02 +0200257/*
258 * Get the number value of a variable.
259 * If it is a String variable, uses vim_str2nr().
260 * For incompatible types, return 0.
261 * tv_get_number_chk() is similar to tv_get_number(), but informs the
262 * caller of incompatible types: it sets *denote to TRUE if "denote"
263 * is not NULL or returns -1 otherwise.
264 */
265 varnumber_T
266tv_get_number(typval_T *varp)
267{
268 int error = FALSE;
269
270 return tv_get_number_chk(varp, &error); // return 0L on error
271}
272
273 varnumber_T
274tv_get_number_chk(typval_T *varp, int *denote)
275{
276 return tv_get_bool_or_number_chk(varp, denote, FALSE);
277}
278
279/*
280 * Get the boolean value of "varp". This is like tv_get_number_chk(),
Bram Moolenaard70840e2020-08-22 15:06:35 +0200281 * but in Vim9 script accepts Number (0 and 1) and Bool/Special.
Bram Moolenaar36967b32020-08-17 21:41:02 +0200282 */
283 varnumber_T
284tv_get_bool(typval_T *varp)
285{
286 return tv_get_bool_or_number_chk(varp, NULL, TRUE);
Bram Moolenaar36967b32020-08-17 21:41:02 +0200287}
288
Bram Moolenaare15eebd2020-08-18 19:11:38 +0200289/*
290 * Get the boolean value of "varp". This is like tv_get_number_chk(),
291 * but in Vim9 script accepts Number and Bool.
292 */
293 varnumber_T
294tv_get_bool_chk(typval_T *varp, int *denote)
295{
296 return tv_get_bool_or_number_chk(varp, denote, TRUE);
Bram Moolenaare15eebd2020-08-18 19:11:38 +0200297}
298
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200299#if defined(FEAT_FLOAT) || defined(PROTO)
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200300 float_T
301tv_get_float(typval_T *varp)
302{
303 switch (varp->v_type)
304 {
305 case VAR_NUMBER:
306 return (float_T)(varp->vval.v_number);
307 case VAR_FLOAT:
308 return varp->vval.v_float;
309 case VAR_FUNC:
310 case VAR_PARTIAL:
311 emsg(_("E891: Using a Funcref as a Float"));
312 break;
313 case VAR_STRING:
314 emsg(_("E892: Using a String as a Float"));
315 break;
316 case VAR_LIST:
317 emsg(_("E893: Using a List as a Float"));
318 break;
319 case VAR_DICT:
320 emsg(_("E894: Using a Dictionary as a Float"));
321 break;
322 case VAR_BOOL:
323 emsg(_("E362: Using a boolean value as a Float"));
324 break;
325 case VAR_SPECIAL:
326 emsg(_("E907: Using a special value as a Float"));
327 break;
328 case VAR_JOB:
329# ifdef FEAT_JOB_CHANNEL
330 emsg(_("E911: Using a Job as a Float"));
331 break;
332# endif
333 case VAR_CHANNEL:
334# ifdef FEAT_JOB_CHANNEL
335 emsg(_("E914: Using a Channel as a Float"));
336 break;
337# endif
338 case VAR_BLOB:
339 emsg(_("E975: Using a Blob as a Float"));
340 break;
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200341 case VAR_VOID:
342 emsg(_(e_cannot_use_void_value));
343 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200344 case VAR_UNKNOWN:
345 case VAR_ANY:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200346 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200347 internal_error_no_abort("tv_get_float(UNKNOWN)");
348 break;
349 }
350 return 0;
351}
352#endif
353
354/*
Yegappan Lakshmanana9a7c0c2021-07-17 19:11:07 +0200355 * Give an error and return FAIL unless "args[idx]" is a string.
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100356 */
357 int
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100358check_for_string_arg(typval_T *args, int idx)
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100359{
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100360 if (args[idx].v_type != VAR_STRING)
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100361 {
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100362 if (idx >= 0)
363 semsg(_(e_string_required_for_argument_nr), idx + 1);
Bram Moolenaarf28f2ac2021-03-22 22:21:26 +0100364 else
365 emsg(_(e_stringreq));
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100366 return FAIL;
367 }
368 return OK;
369}
370
371/*
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100372 * Give an error and return FAIL unless "args[idx]" is a non-empty string.
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100373 */
374 int
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100375check_for_nonempty_string_arg(typval_T *args, int idx)
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100376{
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100377 if (check_for_string_arg(args, idx) == FAIL)
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100378 return FAIL;
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100379 if (args[idx].vval.v_string == NULL || *args[idx].vval.v_string == NUL)
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100380 {
Bram Moolenaare8e30782021-04-10 21:46:05 +0200381 semsg(_(e_non_empty_string_required_for_argument_nr), idx + 1);
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100382 return FAIL;
383 }
384 return OK;
385}
386
387/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200388 * Check for an optional string argument at 'idx'
389 */
390 int
391check_for_opt_string_arg(typval_T *args, int idx)
392{
393 return (args[idx].v_type == VAR_UNKNOWN
394 || check_for_string_arg(args, idx) != FAIL);
395}
396
397/*
Yegappan Lakshmanana9a7c0c2021-07-17 19:11:07 +0200398 * Give an error and return FAIL unless "args[idx]" is a number.
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200399 */
400 int
401check_for_number_arg(typval_T *args, int idx)
402{
403 if (args[idx].v_type != VAR_NUMBER)
404 {
405 if (idx >= 0)
406 semsg(_(e_number_required_for_argument_nr), idx + 1);
407 else
408 emsg(_(e_numberreq));
409 return FAIL;
410 }
411 return OK;
412}
413
414/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200415 * Check for an optional number argument at 'idx'
416 */
417 int
418check_for_opt_number_arg(typval_T *args, int idx)
419{
420 return (args[idx].v_type == VAR_UNKNOWN
421 || check_for_number_arg(args, idx) != FAIL);
422}
423
424/*
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200425 * Give an error and return FAIL unless "args[idx]" is a float or a number.
426 */
427 int
428check_for_float_or_nr_arg(typval_T *args, int idx)
429{
430 if (args[idx].v_type != VAR_FLOAT && args[idx].v_type != VAR_NUMBER)
431 {
432 if (idx >= 0)
433 semsg(_(e_number_required_for_argument_nr), idx + 1);
434 else
435 emsg(_(e_numberreq));
436 return FAIL;
437 }
438 return OK;
439}
440
441/*
Yegappan Lakshmanana9a7c0c2021-07-17 19:11:07 +0200442 * Give an error and return FAIL unless "args[idx]" is a bool.
443 */
444 int
445check_for_bool_arg(typval_T *args, int idx)
446{
447 if (args[idx].v_type != VAR_BOOL
448 && !(args[idx].v_type == VAR_NUMBER
449 && (args[idx].vval.v_number == 0
450 || args[idx].vval.v_number == 1)))
451 {
452 if (idx >= 0)
453 semsg(_(e_bool_required_for_argument_nr), idx + 1);
454 else
455 emsg(_(e_boolreq));
456 return FAIL;
457 }
458 return OK;
459}
460
461/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200462 * Check for an optional bool argument at 'idx'
463 */
464 int
465check_for_opt_bool_arg(typval_T *args, int idx)
466{
467 return (args[idx].v_type == VAR_UNKNOWN
468 || check_for_bool_arg(args, idx) != FAIL);
469}
470
471/*
Yegappan Lakshmanana9a7c0c2021-07-17 19:11:07 +0200472 * Give an error and return FAIL unless "args[idx]" is a list.
473 */
474 int
475check_for_list_arg(typval_T *args, int idx)
476{
477 if (args[idx].v_type != VAR_LIST)
478 {
479 if (idx >= 0)
480 semsg(_(e_list_required_for_argument_nr), idx + 1);
481 else
482 emsg(_(e_listreq));
483 return FAIL;
484 }
485 return OK;
486}
487
488/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200489 * Check for an optional list argument at 'idx'
490 */
491 int
492check_for_opt_list_arg(typval_T *args, int idx)
493{
494 return (args[idx].v_type == VAR_UNKNOWN
495 || check_for_list_arg(args, idx) != FAIL);
496}
497
498/*
Yegappan Lakshmanana9a7c0c2021-07-17 19:11:07 +0200499 * Give an error and return FAIL unless "args[idx]" is a dict.
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200500 */
501 int
502check_for_dict_arg(typval_T *args, int idx)
503{
504 if (args[idx].v_type != VAR_DICT)
505 {
506 if (idx >= 0)
507 semsg(_(e_dict_required_for_argument_nr), idx + 1);
508 else
509 emsg(_(e_dictreq));
510 return FAIL;
511 }
512 return OK;
513}
514
515/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200516 * Check for an optional dict argument at 'idx'
517 */
518 int
519check_for_opt_dict_arg(typval_T *args, int idx)
520{
521 return (args[idx].v_type == VAR_UNKNOWN
522 || check_for_dict_arg(args, idx) != FAIL);
523}
524
525/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200526 * Give an error and return FAIL unless "args[idx]" is a channel or a job.
527 */
528 int
529check_for_chan_or_job_arg(typval_T *args, int idx)
530{
531 if (args[idx].v_type != VAR_CHANNEL && args[idx].v_type != VAR_JOB)
532 {
533 if (idx >= 0)
534 semsg(_(e_chan_or_job_required_for_argument_nr), idx + 1);
535 else
536 emsg(_(e_chan_or_job_req));
537 return FAIL;
538 }
539 return OK;
540}
541
542/*
Yegappan Lakshmanan7973de32021-07-24 16:16:15 +0200543 * Give an error and return FAIL unless "args[idx]" is an optional channel or a
544 * job.
545 */
546 int
547check_for_opt_chan_or_job_arg(typval_T *args, int idx)
548{
549 return (args[idx].v_type == VAR_UNKNOWN
550 || check_for_chan_or_job_arg(args, idx) != FAIL);
551}
552
553/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200554 * Give an error and return FAIL unless "args[idx]" is a job.
555 */
556 int
557check_for_job_arg(typval_T *args, int idx)
558{
559 if (args[idx].v_type != VAR_JOB)
560 {
561 if (idx >= 0)
562 semsg(_(e_job_required_for_argument_nr), idx + 1);
563 else
564 emsg(_(e_jobreq));
565 return FAIL;
566 }
567 return OK;
568}
569
570/*
571 * Give an error and return FAIL unless "args[idx]" is a string or
572 * a number.
573 */
574 int
575check_for_string_or_number_arg(typval_T *args, int idx)
576{
577 if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
578 {
579 if (idx >= 0)
580 semsg(_(e_string_required_for_argument_nr), idx + 1);
581 else
582 emsg(_(e_stringreq));
583 return FAIL;
584 }
585 return OK;
586}
587
588/*
Yegappan Lakshmanancd917202021-07-21 19:09:09 +0200589 * Check for an optional string or number argument at 'idx'.
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200590 */
591 int
592check_for_opt_string_or_number_arg(typval_T *args, int idx)
593{
594 return (args[idx].v_type == VAR_UNKNOWN
595 || check_for_string_or_number_arg(args, idx) != FAIL);
596}
597
598/*
Yegappan Lakshmanancd917202021-07-21 19:09:09 +0200599 * Give an error and return FAIL unless "args[idx]" is a buffer number.
600 * Buffer number can be a number or a string.
601 */
602 int
603check_for_buffer_arg(typval_T *args, int idx)
604{
605 return check_for_string_or_number_arg(args, idx);
606}
607
608/*
609 * Check for an optional buffer argument at 'idx'
610 */
611 int
612check_for_opt_buffer_arg(typval_T *args, int idx)
613{
614 return (args[idx].v_type == VAR_UNKNOWN
615 || check_for_buffer_arg(args, idx));
616}
617
618/*
619 * Give an error and return FAIL unless "args[idx]" is a line number.
620 * Line number can be a number or a string.
621 */
622 int
623check_for_lnum_arg(typval_T *args, int idx)
624{
625 return check_for_string_or_number_arg(args, idx);
626}
627
628/*
629 * Check for an optional line number argument at 'idx'
630 */
631 int
632check_for_opt_lnum_arg(typval_T *args, int idx)
633{
634 return (args[idx].v_type == VAR_UNKNOWN
635 || check_for_lnum_arg(args, idx));
636}
637
638/*
Yegappan Lakshmanan0ad871d2021-07-23 20:37:56 +0200639 * Give an error and return FAIL unless "args[idx]" is a string or a blob.
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200640 */
641 int
642check_for_string_or_blob_arg(typval_T *args, int idx)
643{
644 if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_BLOB)
645 {
646 if (idx >= 0)
647 semsg(_(e_string_required_for_argument_nr), idx + 1);
648 else
649 emsg(_(e_stringreq));
650 return FAIL;
651 }
652 return OK;
653}
654
655/*
Yegappan Lakshmanan0ad871d2021-07-23 20:37:56 +0200656 * Give an error and return FAIL unless "args[idx]" is a string or a list.
Yegappan Lakshmanancd917202021-07-21 19:09:09 +0200657 */
658 int
659check_for_string_or_list_arg(typval_T *args, int idx)
660{
661 if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_LIST)
662 {
663 if (idx >= 0)
664 semsg(_(e_string_required_for_argument_nr), idx + 1);
665 else
666 emsg(_(e_stringreq));
667 return FAIL;
668 }
669 return OK;
670}
671
672/*
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200673 * Check for an optional string or list argument at 'idx'
674 */
675 int
676check_for_opt_string_or_list_arg(typval_T *args, int idx)
677{
678 return (args[idx].v_type == VAR_UNKNOWN
679 || check_for_string_or_list_arg(args, idx));
680}
681
682/*
Yegappan Lakshmanan0ad871d2021-07-23 20:37:56 +0200683 * Give an error and return FAIL unless "args[idx]" is a list or a blob.
684 */
685 int
686check_for_list_or_blob_arg(typval_T *args, int idx)
687{
688 if (args[idx].v_type != VAR_LIST && args[idx].v_type != VAR_BLOB)
689 {
690 if (idx >= 0)
691 semsg(_(e_list_required_for_argument_nr), idx + 1);
692 else
693 emsg(_(e_listreq));
694 return FAIL;
695 }
696 return OK;
697}
698
699/*
700 * Give an error and return FAIL unless "args[idx]" is a list or dict or a
701 * blob.
702 */
703 int
704check_for_list_or_dict_or_blob_arg(typval_T *args, int idx)
705{
706 if (args[idx].v_type != VAR_LIST
707 && args[idx].v_type != VAR_DICT
708 && args[idx].v_type != VAR_BLOB)
709 {
710 if (idx >= 0)
711 semsg(_(e_list_required_for_argument_nr), idx + 1);
712 else
713 emsg(_(e_listreq));
714 return FAIL;
715 }
716 return OK;
717}
718
719/*
720 * Give an error and return FAIL unless "args[idx]" is a buffer number or a
721 * dict.
Yegappan Lakshmanancd917202021-07-21 19:09:09 +0200722 */
723 int
724check_for_buffer_or_dict_arg(typval_T *args, int idx)
725{
726 if (args[idx].v_type != VAR_STRING
727 && args[idx].v_type != VAR_NUMBER
728 && args[idx].v_type != VAR_DICT)
729 {
730 if (idx >= 0)
731 semsg(_(e_string_required_for_argument_nr), idx + 1);
732 else
733 emsg(_(e_stringreq));
734 return FAIL;
735 }
736 return OK;
737}
738
739/*
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200740 * Get the string value of a variable.
741 * If it is a Number variable, the number is converted into a string.
742 * tv_get_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
743 * tv_get_string_buf() uses a given buffer.
744 * If the String variable has never been set, return an empty string.
745 * Never returns NULL;
746 * tv_get_string_chk() and tv_get_string_buf_chk() are similar, but return
747 * NULL on error.
748 */
749 char_u *
750tv_get_string(typval_T *varp)
751{
752 static char_u mybuf[NUMBUFLEN];
753
754 return tv_get_string_buf(varp, mybuf);
755}
756
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100757/*
758 * Like tv_get_string() but don't allow number to string conversion for Vim9.
759 */
760 char_u *
761tv_get_string_strict(typval_T *varp)
762{
763 static char_u mybuf[NUMBUFLEN];
764 char_u *res = tv_get_string_buf_chk_strict(
765 varp, mybuf, in_vim9script());
766
767 return res != NULL ? res : (char_u *)"";
768}
769
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200770 char_u *
771tv_get_string_buf(typval_T *varp, char_u *buf)
772{
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200773 char_u *res = tv_get_string_buf_chk(varp, buf);
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200774
775 return res != NULL ? res : (char_u *)"";
776}
777
778/*
779 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
780 */
781 char_u *
782tv_get_string_chk(typval_T *varp)
783{
784 static char_u mybuf[NUMBUFLEN];
785
786 return tv_get_string_buf_chk(varp, mybuf);
787}
788
789 char_u *
790tv_get_string_buf_chk(typval_T *varp, char_u *buf)
791{
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100792 return tv_get_string_buf_chk_strict(varp, buf, FALSE);
793}
794
795 char_u *
796tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
797{
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200798 switch (varp->v_type)
799 {
800 case VAR_NUMBER:
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100801 if (strict)
802 {
803 emsg(_(e_using_number_as_string));
804 break;
805 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200806 vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
807 (varnumber_T)varp->vval.v_number);
808 return buf;
809 case VAR_FUNC:
810 case VAR_PARTIAL:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200811 emsg(_("E729: Using a Funcref as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200812 break;
813 case VAR_LIST:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200814 emsg(_("E730: Using a List as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200815 break;
816 case VAR_DICT:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200817 emsg(_("E731: Using a Dictionary as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200818 break;
819 case VAR_FLOAT:
820#ifdef FEAT_FLOAT
Bram Moolenaar7a2217b2021-06-06 12:33:49 +0200821 if (strict)
822 {
823 emsg(_(e_float_as_string));
824 break;
825 }
826 vim_snprintf((char *)buf, NUMBUFLEN, "%g", varp->vval.v_float);
827 return buf;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200828#endif
829 case VAR_STRING:
830 if (varp->vval.v_string != NULL)
831 return varp->vval.v_string;
832 return (char_u *)"";
833 case VAR_BOOL:
834 case VAR_SPECIAL:
835 STRCPY(buf, get_var_special_name(varp->vval.v_number));
836 return buf;
837 case VAR_BLOB:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200838 emsg(_("E976: Using a Blob as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200839 break;
840 case VAR_JOB:
841#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200842 if (in_vim9script())
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200843 {
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200844 semsg(_(e_using_invalid_value_as_string_str), "job");
845 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200846 }
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200847 return job_to_string_buf(varp, buf);
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200848#endif
849 break;
850 case VAR_CHANNEL:
851#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200852 if (in_vim9script())
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200853 {
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200854 semsg(_(e_using_invalid_value_as_string_str), "channel");
855 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200856 }
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200857 return channel_to_string_buf(varp, buf);
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200858#endif
859 break;
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200860 case VAR_VOID:
861 emsg(_(e_cannot_use_void_value));
862 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200863 case VAR_UNKNOWN:
864 case VAR_ANY:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200865 case VAR_INSTR:
Bram Moolenaar68db9962021-05-09 23:19:22 +0200866 semsg(_(e_using_invalid_value_as_string_str),
867 vartype_name(varp->v_type));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200868 break;
869 }
870 return NULL;
871}
872
873/*
874 * Turn a typeval into a string. Similar to tv_get_string_buf() but uses
875 * string() on Dict, List, etc.
876 */
877 char_u *
878tv_stringify(typval_T *varp, char_u *buf)
879{
880 if (varp->v_type == VAR_LIST
881 || varp->v_type == VAR_DICT
882 || varp->v_type == VAR_BLOB
883 || varp->v_type == VAR_FUNC
884 || varp->v_type == VAR_PARTIAL
885 || varp->v_type == VAR_FLOAT)
886 {
887 typval_T tmp;
888
889 f_string(varp, &tmp);
890 tv_get_string_buf(&tmp, buf);
891 clear_tv(varp);
892 *varp = tmp;
893 return tmp.vval.v_string;
894 }
895 return tv_get_string_buf(varp, buf);
896}
897
898/*
899 * Return TRUE if typeval "tv" and its value are set to be locked (immutable).
900 * Also give an error message, using "name" or _("name") when use_gettext is
901 * TRUE.
902 */
903 int
904tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
905{
906 int lock = 0;
907
908 switch (tv->v_type)
909 {
910 case VAR_BLOB:
911 if (tv->vval.v_blob != NULL)
912 lock = tv->vval.v_blob->bv_lock;
913 break;
914 case VAR_LIST:
915 if (tv->vval.v_list != NULL)
916 lock = tv->vval.v_list->lv_lock;
917 break;
918 case VAR_DICT:
919 if (tv->vval.v_dict != NULL)
920 lock = tv->vval.v_dict->dv_lock;
921 break;
922 default:
923 break;
924 }
Bram Moolenaara187c432020-09-16 21:08:28 +0200925 return value_check_lock(tv->v_lock, name, use_gettext)
926 || (lock != 0 && value_check_lock(lock, name, use_gettext));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200927}
928
929/*
930 * Copy the values from typval_T "from" to typval_T "to".
931 * When needed allocates string or increases reference count.
932 * Does not make a copy of a list, blob or dict but copies the reference!
933 * It is OK for "from" and "to" to point to the same item. This is used to
934 * make a copy later.
935 */
936 void
937copy_tv(typval_T *from, typval_T *to)
938{
939 to->v_type = from->v_type;
940 to->v_lock = 0;
941 switch (from->v_type)
942 {
943 case VAR_NUMBER:
944 case VAR_BOOL:
945 case VAR_SPECIAL:
946 to->vval.v_number = from->vval.v_number;
947 break;
948 case VAR_FLOAT:
949#ifdef FEAT_FLOAT
950 to->vval.v_float = from->vval.v_float;
951 break;
952#endif
953 case VAR_JOB:
954#ifdef FEAT_JOB_CHANNEL
955 to->vval.v_job = from->vval.v_job;
956 if (to->vval.v_job != NULL)
957 ++to->vval.v_job->jv_refcount;
958 break;
959#endif
960 case VAR_CHANNEL:
961#ifdef FEAT_JOB_CHANNEL
962 to->vval.v_channel = from->vval.v_channel;
963 if (to->vval.v_channel != NULL)
964 ++to->vval.v_channel->ch_refcount;
965 break;
966#endif
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200967 case VAR_INSTR:
968 to->vval.v_instr = from->vval.v_instr;
969 break;
970
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200971 case VAR_STRING:
972 case VAR_FUNC:
973 if (from->vval.v_string == NULL)
974 to->vval.v_string = NULL;
975 else
976 {
977 to->vval.v_string = vim_strsave(from->vval.v_string);
978 if (from->v_type == VAR_FUNC)
979 func_ref(to->vval.v_string);
980 }
981 break;
982 case VAR_PARTIAL:
983 if (from->vval.v_partial == NULL)
984 to->vval.v_partial = NULL;
985 else
986 {
987 to->vval.v_partial = from->vval.v_partial;
988 ++to->vval.v_partial->pt_refcount;
989 }
990 break;
991 case VAR_BLOB:
992 if (from->vval.v_blob == NULL)
993 to->vval.v_blob = NULL;
994 else
995 {
996 to->vval.v_blob = from->vval.v_blob;
997 ++to->vval.v_blob->bv_refcount;
998 }
999 break;
1000 case VAR_LIST:
1001 if (from->vval.v_list == NULL)
1002 to->vval.v_list = NULL;
1003 else
1004 {
1005 to->vval.v_list = from->vval.v_list;
1006 ++to->vval.v_list->lv_refcount;
1007 }
1008 break;
1009 case VAR_DICT:
1010 if (from->vval.v_dict == NULL)
1011 to->vval.v_dict = NULL;
1012 else
1013 {
1014 to->vval.v_dict = from->vval.v_dict;
1015 ++to->vval.v_dict->dv_refcount;
1016 }
1017 break;
Bram Moolenaar61a417b2021-06-15 22:54:28 +02001018 case VAR_VOID:
1019 emsg(_(e_cannot_use_void_value));
1020 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001021 case VAR_UNKNOWN:
1022 case VAR_ANY:
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001023 internal_error_no_abort("copy_tv(UNKNOWN)");
1024 break;
1025 }
1026}
1027
1028/*
1029 * Compare "typ1" and "typ2". Put the result in "typ1".
1030 */
1031 int
1032typval_compare(
1033 typval_T *typ1, // first operand
1034 typval_T *typ2, // second operand
Bram Moolenaar657137c2021-01-09 15:45:23 +01001035 exprtype_T type, // operator
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001036 int ic) // ignore case
1037{
1038 int i;
1039 varnumber_T n1, n2;
1040 char_u *s1, *s2;
1041 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1042 int type_is = type == EXPR_IS || type == EXPR_ISNOT;
1043
1044 if (type_is && typ1->v_type != typ2->v_type)
1045 {
1046 // For "is" a different type always means FALSE, for "notis"
1047 // it means TRUE.
1048 n1 = (type == EXPR_ISNOT);
1049 }
1050 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
1051 {
1052 if (type_is)
1053 {
1054 n1 = (typ1->v_type == typ2->v_type
1055 && typ1->vval.v_blob == typ2->vval.v_blob);
1056 if (type == EXPR_ISNOT)
1057 n1 = !n1;
1058 }
1059 else if (typ1->v_type != typ2->v_type
1060 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1061 {
1062 if (typ1->v_type != typ2->v_type)
1063 emsg(_("E977: Can only compare Blob with Blob"));
1064 else
1065 emsg(_(e_invalblob));
1066 clear_tv(typ1);
1067 return FAIL;
1068 }
1069 else
1070 {
1071 // Compare two Blobs for being equal or unequal.
1072 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
1073 if (type == EXPR_NEQUAL)
1074 n1 = !n1;
1075 }
1076 }
1077 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
1078 {
1079 if (type_is)
1080 {
1081 n1 = (typ1->v_type == typ2->v_type
1082 && typ1->vval.v_list == typ2->vval.v_list);
1083 if (type == EXPR_ISNOT)
1084 n1 = !n1;
1085 }
1086 else if (typ1->v_type != typ2->v_type
1087 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1088 {
1089 if (typ1->v_type != typ2->v_type)
1090 emsg(_("E691: Can only compare List with List"));
1091 else
1092 emsg(_("E692: Invalid operation for List"));
1093 clear_tv(typ1);
1094 return FAIL;
1095 }
1096 else
1097 {
1098 // Compare two Lists for being equal or unequal.
1099 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
1100 ic, FALSE);
1101 if (type == EXPR_NEQUAL)
1102 n1 = !n1;
1103 }
1104 }
1105
1106 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
1107 {
1108 if (type_is)
1109 {
1110 n1 = (typ1->v_type == typ2->v_type
1111 && typ1->vval.v_dict == typ2->vval.v_dict);
1112 if (type == EXPR_ISNOT)
1113 n1 = !n1;
1114 }
1115 else if (typ1->v_type != typ2->v_type
1116 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1117 {
1118 if (typ1->v_type != typ2->v_type)
1119 emsg(_("E735: Can only compare Dictionary with Dictionary"));
1120 else
1121 emsg(_("E736: Invalid operation for Dictionary"));
1122 clear_tv(typ1);
1123 return FAIL;
1124 }
1125 else
1126 {
1127 // Compare two Dictionaries for being equal or unequal.
1128 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
1129 ic, FALSE);
1130 if (type == EXPR_NEQUAL)
1131 n1 = !n1;
1132 }
1133 }
1134
1135 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
1136 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
1137 {
1138 if (type != EXPR_EQUAL && type != EXPR_NEQUAL
1139 && type != EXPR_IS && type != EXPR_ISNOT)
1140 {
1141 emsg(_("E694: Invalid operation for Funcrefs"));
1142 clear_tv(typ1);
1143 return FAIL;
1144 }
1145 if ((typ1->v_type == VAR_PARTIAL
1146 && typ1->vval.v_partial == NULL)
1147 || (typ2->v_type == VAR_PARTIAL
1148 && typ2->vval.v_partial == NULL))
1149 // When both partials are NULL, then they are equal.
1150 // Otherwise they are not equal.
1151 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
1152 else if (type_is)
1153 {
1154 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
1155 // strings are considered the same if their value is
1156 // the same
1157 n1 = tv_equal(typ1, typ2, ic, FALSE);
1158 else if (typ1->v_type == VAR_PARTIAL
1159 && typ2->v_type == VAR_PARTIAL)
1160 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
1161 else
1162 n1 = FALSE;
1163 }
1164 else
1165 n1 = tv_equal(typ1, typ2, ic, FALSE);
1166 if (type == EXPR_NEQUAL || type == EXPR_ISNOT)
1167 n1 = !n1;
1168 }
1169
1170#ifdef FEAT_FLOAT
1171 // If one of the two variables is a float, compare as a float.
1172 // When using "=~" or "!~", always compare as string.
1173 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
1174 && type != EXPR_MATCH && type != EXPR_NOMATCH)
1175 {
1176 float_T f1, f2;
1177
1178 f1 = tv_get_float(typ1);
1179 f2 = tv_get_float(typ2);
1180 n1 = FALSE;
1181 switch (type)
1182 {
1183 case EXPR_IS:
1184 case EXPR_EQUAL: n1 = (f1 == f2); break;
1185 case EXPR_ISNOT:
1186 case EXPR_NEQUAL: n1 = (f1 != f2); break;
1187 case EXPR_GREATER: n1 = (f1 > f2); break;
1188 case EXPR_GEQUAL: n1 = (f1 >= f2); break;
1189 case EXPR_SMALLER: n1 = (f1 < f2); break;
1190 case EXPR_SEQUAL: n1 = (f1 <= f2); break;
1191 case EXPR_UNKNOWN:
1192 case EXPR_MATCH:
1193 default: break; // avoid gcc warning
1194 }
1195 }
1196#endif
1197
1198 // If one of the two variables is a number, compare as a number.
1199 // When using "=~" or "!~", always compare as string.
1200 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
1201 && type != EXPR_MATCH && type != EXPR_NOMATCH)
1202 {
1203 n1 = tv_get_number(typ1);
1204 n2 = tv_get_number(typ2);
1205 switch (type)
1206 {
1207 case EXPR_IS:
1208 case EXPR_EQUAL: n1 = (n1 == n2); break;
1209 case EXPR_ISNOT:
1210 case EXPR_NEQUAL: n1 = (n1 != n2); break;
1211 case EXPR_GREATER: n1 = (n1 > n2); break;
1212 case EXPR_GEQUAL: n1 = (n1 >= n2); break;
1213 case EXPR_SMALLER: n1 = (n1 < n2); break;
1214 case EXPR_SEQUAL: n1 = (n1 <= n2); break;
1215 case EXPR_UNKNOWN:
1216 case EXPR_MATCH:
1217 default: break; // avoid gcc warning
1218 }
1219 }
Bram Moolenaarcff40ff2021-01-09 16:21:37 +01001220 else if (in_vim9script() && (typ1->v_type == VAR_BOOL
Bram Moolenaar0c357522021-07-18 14:43:43 +02001221 || typ2->v_type == VAR_BOOL
1222 || (typ1->v_type == VAR_SPECIAL
1223 && typ2->v_type == VAR_SPECIAL)))
Bram Moolenaarcff40ff2021-01-09 16:21:37 +01001224 {
1225 if (typ1->v_type != typ2->v_type)
1226 {
1227 semsg(_(e_cannot_compare_str_with_str),
1228 vartype_name(typ1->v_type), vartype_name(typ2->v_type));
1229 clear_tv(typ1);
1230 return FAIL;
1231 }
1232 n1 = typ1->vval.v_number;
1233 n2 = typ2->vval.v_number;
1234 switch (type)
1235 {
1236 case EXPR_IS:
1237 case EXPR_EQUAL: n1 = (n1 == n2); break;
1238 case EXPR_ISNOT:
1239 case EXPR_NEQUAL: n1 = (n1 != n2); break;
1240 default:
Bram Moolenaar0c357522021-07-18 14:43:43 +02001241 semsg(_(e_invalid_operation_for_str),
1242 vartype_name(typ1->v_type));
Bram Moolenaarcff40ff2021-01-09 16:21:37 +01001243 clear_tv(typ1);
1244 return FAIL;
1245 }
1246 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001247 else
1248 {
Bram Moolenaar0c357522021-07-18 14:43:43 +02001249 if (in_vim9script()
1250 && ((typ1->v_type != VAR_STRING && typ1->v_type != VAR_SPECIAL)
1251 || (typ2->v_type != VAR_STRING && typ2->v_type != VAR_SPECIAL)))
1252 {
1253 semsg(_(e_cannot_compare_str_with_str),
1254 vartype_name(typ1->v_type), vartype_name(typ2->v_type));
1255 clear_tv(typ1);
1256 return FAIL;
1257 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001258 s1 = tv_get_string_buf(typ1, buf1);
1259 s2 = tv_get_string_buf(typ2, buf2);
1260 if (type != EXPR_MATCH && type != EXPR_NOMATCH)
1261 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
1262 else
1263 i = 0;
1264 n1 = FALSE;
1265 switch (type)
1266 {
1267 case EXPR_IS:
1268 case EXPR_EQUAL: n1 = (i == 0); break;
1269 case EXPR_ISNOT:
1270 case EXPR_NEQUAL: n1 = (i != 0); break;
1271 case EXPR_GREATER: n1 = (i > 0); break;
1272 case EXPR_GEQUAL: n1 = (i >= 0); break;
1273 case EXPR_SMALLER: n1 = (i < 0); break;
1274 case EXPR_SEQUAL: n1 = (i <= 0); break;
1275
1276 case EXPR_MATCH:
1277 case EXPR_NOMATCH:
1278 n1 = pattern_match(s2, s1, ic);
1279 if (type == EXPR_NOMATCH)
1280 n1 = !n1;
1281 break;
1282
1283 default: break; // avoid gcc warning
1284 }
1285 }
1286 clear_tv(typ1);
Bram Moolenaarc71f36a2020-07-21 21:31:00 +02001287 if (in_vim9script())
1288 {
1289 typ1->v_type = VAR_BOOL;
1290 typ1->vval.v_number = n1 ? VVAL_TRUE : VVAL_FALSE;
1291 }
1292 else
1293 {
1294 typ1->v_type = VAR_NUMBER;
1295 typ1->vval.v_number = n1;
1296 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001297
1298 return OK;
1299}
1300
Bram Moolenaar34453202021-01-31 13:08:38 +01001301/*
1302 * Convert any type to a string, never give an error.
1303 * When "quotes" is TRUE add quotes to a string.
1304 * Returns an allocated string.
1305 */
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001306 char_u *
Bram Moolenaar34453202021-01-31 13:08:38 +01001307typval_tostring(typval_T *arg, int quotes)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001308{
1309 char_u *tofree;
1310 char_u numbuf[NUMBUFLEN];
1311 char_u *ret = NULL;
1312
1313 if (arg == NULL)
1314 return vim_strsave((char_u *)"(does not exist)");
Bram Moolenaar34453202021-01-31 13:08:38 +01001315 if (!quotes && arg->v_type == VAR_STRING)
1316 {
1317 ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
1318 : arg->vval.v_string);
1319 }
1320 else
1321 {
1322 ret = tv2string(arg, &tofree, numbuf, 0);
1323 // Make a copy if we have a value but it's not in allocated memory.
1324 if (ret != NULL && tofree == NULL)
1325 ret = vim_strsave(ret);
1326 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001327 return ret;
1328}
1329
1330/*
1331 * Return TRUE if typeval "tv" is locked: Either that value is locked itself
1332 * or it refers to a List or Dictionary that is locked.
1333 */
1334 int
1335tv_islocked(typval_T *tv)
1336{
1337 return (tv->v_lock & VAR_LOCKED)
1338 || (tv->v_type == VAR_LIST
1339 && tv->vval.v_list != NULL
1340 && (tv->vval.v_list->lv_lock & VAR_LOCKED))
1341 || (tv->v_type == VAR_DICT
1342 && tv->vval.v_dict != NULL
1343 && (tv->vval.v_dict->dv_lock & VAR_LOCKED));
1344}
1345
1346 static int
1347func_equal(
1348 typval_T *tv1,
1349 typval_T *tv2,
1350 int ic) // ignore case
1351{
1352 char_u *s1, *s2;
1353 dict_T *d1, *d2;
1354 int a1, a2;
1355 int i;
1356
1357 // empty and NULL function name considered the same
1358 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
1359 : partial_name(tv1->vval.v_partial);
1360 if (s1 != NULL && *s1 == NUL)
1361 s1 = NULL;
1362 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
1363 : partial_name(tv2->vval.v_partial);
1364 if (s2 != NULL && *s2 == NUL)
1365 s2 = NULL;
1366 if (s1 == NULL || s2 == NULL)
1367 {
1368 if (s1 != s2)
1369 return FALSE;
1370 }
1371 else if (STRCMP(s1, s2) != 0)
1372 return FALSE;
1373
1374 // empty dict and NULL dict is different
1375 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
1376 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
1377 if (d1 == NULL || d2 == NULL)
1378 {
1379 if (d1 != d2)
1380 return FALSE;
1381 }
1382 else if (!dict_equal(d1, d2, ic, TRUE))
1383 return FALSE;
1384
1385 // empty list and no list considered the same
1386 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
1387 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
1388 if (a1 != a2)
1389 return FALSE;
1390 for (i = 0; i < a1; ++i)
1391 if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
1392 tv2->vval.v_partial->pt_argv + i, ic, TRUE))
1393 return FALSE;
1394
1395 return TRUE;
1396}
1397
1398/*
1399 * Return TRUE if "tv1" and "tv2" have the same value.
1400 * Compares the items just like "==" would compare them, but strings and
1401 * numbers are different. Floats and numbers are also different.
1402 */
1403 int
1404tv_equal(
1405 typval_T *tv1,
1406 typval_T *tv2,
1407 int ic, // ignore case
1408 int recursive) // TRUE when used recursively
1409{
1410 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1411 char_u *s1, *s2;
1412 static int recursive_cnt = 0; // catch recursive loops
1413 int r;
1414 static int tv_equal_recurse_limit;
1415
1416 // Catch lists and dicts that have an endless loop by limiting
1417 // recursiveness to a limit. We guess they are equal then.
1418 // A fixed limit has the problem of still taking an awful long time.
1419 // Reduce the limit every time running into it. That should work fine for
1420 // deeply linked structures that are not recursively linked and catch
1421 // recursiveness quickly.
1422 if (!recursive)
1423 tv_equal_recurse_limit = 1000;
1424 if (recursive_cnt >= tv_equal_recurse_limit)
1425 {
1426 --tv_equal_recurse_limit;
1427 return TRUE;
1428 }
1429
1430 // For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and
1431 // arguments.
1432 if ((tv1->v_type == VAR_FUNC
1433 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
1434 && (tv2->v_type == VAR_FUNC
1435 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
1436 {
1437 ++recursive_cnt;
1438 r = func_equal(tv1, tv2, ic);
1439 --recursive_cnt;
1440 return r;
1441 }
1442
Bram Moolenaar418a29f2021-02-10 22:23:41 +01001443 if (tv1->v_type != tv2->v_type
1444 && ((tv1->v_type != VAR_BOOL && tv1->v_type != VAR_SPECIAL)
1445 || (tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL)))
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001446 return FALSE;
1447
1448 switch (tv1->v_type)
1449 {
1450 case VAR_LIST:
1451 ++recursive_cnt;
1452 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
1453 --recursive_cnt;
1454 return r;
1455
1456 case VAR_DICT:
1457 ++recursive_cnt;
1458 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
1459 --recursive_cnt;
1460 return r;
1461
1462 case VAR_BLOB:
1463 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
1464
1465 case VAR_NUMBER:
1466 case VAR_BOOL:
1467 case VAR_SPECIAL:
1468 return tv1->vval.v_number == tv2->vval.v_number;
1469
1470 case VAR_STRING:
1471 s1 = tv_get_string_buf(tv1, buf1);
1472 s2 = tv_get_string_buf(tv2, buf2);
1473 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
1474
1475 case VAR_FLOAT:
1476#ifdef FEAT_FLOAT
1477 return tv1->vval.v_float == tv2->vval.v_float;
1478#endif
1479 case VAR_JOB:
1480#ifdef FEAT_JOB_CHANNEL
1481 return tv1->vval.v_job == tv2->vval.v_job;
1482#endif
1483 case VAR_CHANNEL:
1484#ifdef FEAT_JOB_CHANNEL
1485 return tv1->vval.v_channel == tv2->vval.v_channel;
1486#endif
Bram Moolenaarf18332f2021-05-07 17:55:55 +02001487 case VAR_INSTR:
1488 return tv1->vval.v_instr == tv2->vval.v_instr;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001489
1490 case VAR_PARTIAL:
1491 return tv1->vval.v_partial == tv2->vval.v_partial;
1492
1493 case VAR_FUNC:
1494 return tv1->vval.v_string == tv2->vval.v_string;
1495
1496 case VAR_UNKNOWN:
1497 case VAR_ANY:
1498 case VAR_VOID:
1499 break;
1500 }
1501
1502 // VAR_UNKNOWN can be the result of a invalid expression, let's say it
1503 // does not equal anything, not even itself.
1504 return FALSE;
1505}
1506
1507/*
1508 * Get an option value.
1509 * "arg" points to the '&' or '+' before the option name.
1510 * "arg" is advanced to character after the option name.
1511 * Return OK or FAIL.
1512 */
1513 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001514eval_option(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001515 char_u **arg,
1516 typval_T *rettv, // when NULL, only check if option exists
1517 int evaluate)
1518{
1519 char_u *option_end;
1520 long numval;
1521 char_u *stringval;
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001522 getoption_T opt_type;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001523 int c;
1524 int working = (**arg == '+'); // has("+option")
1525 int ret = OK;
1526 int opt_flags;
1527
1528 // Isolate the option name and find its value.
1529 option_end = find_option_end(arg, &opt_flags);
1530 if (option_end == NULL)
1531 {
1532 if (rettv != NULL)
1533 semsg(_("E112: Option name missing: %s"), *arg);
1534 return FAIL;
1535 }
1536
1537 if (!evaluate)
1538 {
1539 *arg = option_end;
1540 return OK;
1541 }
1542
1543 c = *option_end;
1544 *option_end = NUL;
1545 opt_type = get_option_value(*arg, &numval,
1546 rettv == NULL ? NULL : &stringval, opt_flags);
1547
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001548 if (opt_type == gov_unknown)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001549 {
1550 if (rettv != NULL)
1551 semsg(_(e_unknown_option), *arg);
1552 ret = FAIL;
1553 }
1554 else if (rettv != NULL)
1555 {
Bram Moolenaara79925a2021-01-05 17:50:28 +01001556 rettv->v_lock = 0;
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001557 if (opt_type == gov_hidden_string)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001558 {
1559 rettv->v_type = VAR_STRING;
1560 rettv->vval.v_string = NULL;
1561 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001562 else if (opt_type == gov_hidden_bool || opt_type == gov_hidden_number)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001563 {
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001564 rettv->v_type = in_vim9script() && opt_type == gov_hidden_bool
1565 ? VAR_BOOL : VAR_NUMBER;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001566 rettv->vval.v_number = 0;
1567 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001568 else if (opt_type == gov_bool || opt_type == gov_number)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001569 {
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001570 if (in_vim9script() && opt_type == gov_bool)
1571 {
1572 rettv->v_type = VAR_BOOL;
1573 rettv->vval.v_number = numval ? VVAL_TRUE : VVAL_FALSE;
1574 }
1575 else
1576 {
1577 rettv->v_type = VAR_NUMBER;
1578 rettv->vval.v_number = numval;
1579 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001580 }
1581 else // string option
1582 {
1583 rettv->v_type = VAR_STRING;
1584 rettv->vval.v_string = stringval;
1585 }
1586 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001587 else if (working && (opt_type == gov_hidden_bool
1588 || opt_type == gov_hidden_number
1589 || opt_type == gov_hidden_string))
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001590 ret = FAIL;
1591
1592 *option_end = c; // put back for error messages
1593 *arg = option_end;
1594
1595 return ret;
1596}
1597
1598/*
1599 * Allocate a variable for a number constant. Also deals with "0z" for blob.
1600 * Return OK or FAIL.
1601 */
1602 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001603eval_number(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001604 char_u **arg,
1605 typval_T *rettv,
1606 int evaluate,
1607 int want_string UNUSED)
1608{
1609 int len;
1610#ifdef FEAT_FLOAT
1611 char_u *p;
1612 int get_float = FALSE;
1613
1614 // We accept a float when the format matches
1615 // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
1616 // strict to avoid backwards compatibility problems.
1617 // With script version 2 and later the leading digit can be
1618 // omitted.
1619 // Don't look for a float after the "." operator, so that
1620 // ":let vers = 1.2.3" doesn't fail.
1621 if (**arg == '.')
1622 p = *arg;
1623 else
1624 p = skipdigits(*arg + 1);
1625 if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
1626 {
1627 get_float = TRUE;
1628 p = skipdigits(p + 2);
1629 if (*p == 'e' || *p == 'E')
1630 {
1631 ++p;
1632 if (*p == '-' || *p == '+')
1633 ++p;
1634 if (!vim_isdigit(*p))
1635 get_float = FALSE;
1636 else
1637 p = skipdigits(p + 1);
1638 }
1639 if (ASCII_ISALPHA(*p) || *p == '.')
1640 get_float = FALSE;
1641 }
1642 if (get_float)
1643 {
1644 float_T f;
1645
1646 *arg += string2float(*arg, &f);
1647 if (evaluate)
1648 {
1649 rettv->v_type = VAR_FLOAT;
1650 rettv->vval.v_float = f;
1651 }
1652 }
1653 else
1654#endif
1655 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
1656 {
1657 char_u *bp;
1658 blob_T *blob = NULL; // init for gcc
1659
1660 // Blob constant: 0z0123456789abcdef
1661 if (evaluate)
1662 blob = blob_alloc();
1663 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
1664 {
1665 if (!vim_isxdigit(bp[1]))
1666 {
1667 if (blob != NULL)
1668 {
1669 emsg(_("E973: Blob literal should have an even number of hex characters"));
1670 ga_clear(&blob->bv_ga);
1671 VIM_CLEAR(blob);
1672 }
1673 return FAIL;
1674 }
1675 if (blob != NULL)
1676 ga_append(&blob->bv_ga,
1677 (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
1678 if (bp[2] == '.' && vim_isxdigit(bp[3]))
1679 ++bp;
1680 }
1681 if (blob != NULL)
1682 rettv_blob_set(rettv, blob);
1683 *arg = bp;
1684 }
1685 else
1686 {
1687 varnumber_T n;
1688
1689 // decimal, hex or octal number
1690 vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4
1691 ? STR2NR_NO_OCT + STR2NR_QUOTE
1692 : STR2NR_ALL, &n, NULL, 0, TRUE);
1693 if (len == 0)
1694 {
Bram Moolenaar108010a2021-06-27 22:03:33 +02001695 semsg(_(e_invalid_expression_str), *arg);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001696 return FAIL;
1697 }
1698 *arg += len;
1699 if (evaluate)
1700 {
1701 rettv->v_type = VAR_NUMBER;
1702 rettv->vval.v_number = n;
1703 }
1704 }
1705 return OK;
1706}
1707
1708/*
1709 * Allocate a variable for a string constant.
1710 * Return OK or FAIL.
1711 */
1712 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001713eval_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001714{
1715 char_u *p;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001716 char_u *end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001717 int extra = 0;
1718 int len;
1719
1720 // Find the end of the string, skipping backslashed characters.
1721 for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
1722 {
1723 if (*p == '\\' && p[1] != NUL)
1724 {
1725 ++p;
1726 // A "\<x>" form occupies at least 4 characters, and produces up
1727 // to 21 characters (3 * 6 for the char and 3 for a modifier):
1728 // reserve space for 18 extra.
1729 // Each byte in the char could be encoded as K_SPECIAL K_EXTRA x.
1730 if (*p == '<')
1731 extra += 18;
1732 }
1733 }
1734
1735 if (*p != '"')
1736 {
1737 semsg(_("E114: Missing quote: %s"), *arg);
1738 return FAIL;
1739 }
1740
1741 // If only parsing, set *arg and return here
1742 if (!evaluate)
1743 {
1744 *arg = p + 1;
1745 return OK;
1746 }
1747
1748 // Copy the string into allocated memory, handling backslashed
1749 // characters.
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001750 rettv->v_type = VAR_STRING;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001751 len = (int)(p - *arg + extra);
1752 rettv->vval.v_string = alloc(len);
1753 if (rettv->vval.v_string == NULL)
1754 return FAIL;
1755 end = rettv->vval.v_string;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001756
1757 for (p = *arg + 1; *p != NUL && *p != '"'; )
1758 {
1759 if (*p == '\\')
1760 {
1761 switch (*++p)
1762 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001763 case 'b': *end++ = BS; ++p; break;
1764 case 'e': *end++ = ESC; ++p; break;
1765 case 'f': *end++ = FF; ++p; break;
1766 case 'n': *end++ = NL; ++p; break;
1767 case 'r': *end++ = CAR; ++p; break;
1768 case 't': *end++ = TAB; ++p; break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001769
1770 case 'X': // hex: "\x1", "\x12"
1771 case 'x':
1772 case 'u': // Unicode: "\u0023"
1773 case 'U':
1774 if (vim_isxdigit(p[1]))
1775 {
1776 int n, nr;
1777 int c = toupper(*p);
1778
1779 if (c == 'X')
1780 n = 2;
1781 else if (*p == 'u')
1782 n = 4;
1783 else
1784 n = 8;
1785 nr = 0;
1786 while (--n >= 0 && vim_isxdigit(p[1]))
1787 {
1788 ++p;
1789 nr = (nr << 4) + hex2nr(*p);
1790 }
1791 ++p;
1792 // For "\u" store the number according to
1793 // 'encoding'.
1794 if (c != 'X')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001795 end += (*mb_char2bytes)(nr, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001796 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001797 *end++ = nr;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001798 }
1799 break;
1800
1801 // octal: "\1", "\12", "\123"
1802 case '0':
1803 case '1':
1804 case '2':
1805 case '3':
1806 case '4':
1807 case '5':
1808 case '6':
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001809 case '7': *end = *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001810 if (*p >= '0' && *p <= '7')
1811 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001812 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001813 if (*p >= '0' && *p <= '7')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001814 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001815 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001816 ++end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001817 break;
1818
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001819 // Special key, e.g.: "\<C-W>"
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001820 case '<':
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001821 {
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001822 int flags = FSK_KEYCODE | FSK_IN_STRING;
1823
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001824 if (p[1] != '*')
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001825 flags |= FSK_SIMPLIFY;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001826 extra = trans_special(&p, end, flags, NULL);
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001827 if (extra != 0)
1828 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001829 end += extra;
1830 if (end >= rettv->vval.v_string + len)
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001831 iemsg("eval_string() used more space than allocated");
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001832 break;
1833 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001834 }
1835 // FALLTHROUGH
1836
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001837 default: MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001838 break;
1839 }
1840 }
1841 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001842 MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001843 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001844 *end = NUL;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001845 if (*p != NUL) // just in case
1846 ++p;
1847 *arg = p;
1848
1849 return OK;
1850}
1851
1852/*
1853 * Allocate a variable for a 'str''ing' constant.
1854 * Return OK or FAIL.
1855 */
1856 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001857eval_lit_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001858{
1859 char_u *p;
1860 char_u *str;
1861 int reduce = 0;
1862
1863 // Find the end of the string, skipping ''.
1864 for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
1865 {
1866 if (*p == '\'')
1867 {
1868 if (p[1] != '\'')
1869 break;
1870 ++reduce;
1871 ++p;
1872 }
1873 }
1874
1875 if (*p != '\'')
1876 {
1877 semsg(_("E115: Missing quote: %s"), *arg);
1878 return FAIL;
1879 }
1880
1881 // If only parsing return after setting "*arg"
1882 if (!evaluate)
1883 {
1884 *arg = p + 1;
1885 return OK;
1886 }
1887
1888 // Copy the string into allocated memory, handling '' to ' reduction.
1889 str = alloc((p - *arg) - reduce);
1890 if (str == NULL)
1891 return FAIL;
1892 rettv->v_type = VAR_STRING;
1893 rettv->vval.v_string = str;
1894
1895 for (p = *arg + 1; *p != NUL; )
1896 {
1897 if (*p == '\'')
1898 {
1899 if (p[1] != '\'')
1900 break;
1901 ++p;
1902 }
1903 MB_COPY_CHAR(p, str);
1904 }
1905 *str = NUL;
1906 *arg = p + 1;
1907
1908 return OK;
1909}
1910
1911/*
1912 * Return a string with the string representation of a variable.
1913 * If the memory is allocated "tofree" is set to it, otherwise NULL.
1914 * "numbuf" is used for a number.
1915 * Puts quotes around strings, so that they can be parsed back by eval().
1916 * May return NULL.
1917 */
1918 char_u *
1919tv2string(
1920 typval_T *tv,
1921 char_u **tofree,
1922 char_u *numbuf,
1923 int copyID)
1924{
1925 return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
1926}
1927
1928/*
1929 * Get the value of an environment variable.
1930 * "arg" is pointing to the '$'. It is advanced to after the name.
1931 * If the environment variable was not set, silently assume it is empty.
1932 * Return FAIL if the name is invalid.
1933 */
1934 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001935eval_env_var(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001936{
1937 char_u *string = NULL;
1938 int len;
1939 int cc;
1940 char_u *name;
1941 int mustfree = FALSE;
1942
1943 ++*arg;
1944 name = *arg;
1945 len = get_env_len(arg);
1946 if (evaluate)
1947 {
1948 if (len == 0)
1949 return FAIL; // invalid empty name
1950
1951 cc = name[len];
1952 name[len] = NUL;
1953 // first try vim_getenv(), fast for normal environment vars
1954 string = vim_getenv(name, &mustfree);
1955 if (string != NULL && *string != NUL)
1956 {
1957 if (!mustfree)
1958 string = vim_strsave(string);
1959 }
1960 else
1961 {
1962 if (mustfree)
1963 vim_free(string);
1964
1965 // next try expanding things like $VIM and ${HOME}
1966 string = expand_env_save(name - 1);
1967 if (string != NULL && *string == '$')
1968 VIM_CLEAR(string);
1969 }
1970 name[len] = cc;
1971
1972 rettv->v_type = VAR_STRING;
1973 rettv->vval.v_string = string;
1974 }
1975
1976 return OK;
1977}
1978
1979/*
1980 * Get the lnum from the first argument.
1981 * Also accepts ".", "$", etc., but that only works for the current buffer.
1982 * Returns -1 on error.
1983 */
1984 linenr_T
1985tv_get_lnum(typval_T *argvars)
1986{
Bram Moolenaar9a963372020-12-21 21:58:46 +01001987 linenr_T lnum = -1;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001988
Bram Moolenaar56acb092020-08-16 14:48:19 +02001989 if (argvars[0].v_type != VAR_STRING || !in_vim9script())
1990 lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL);
Bram Moolenaarf6bdd822021-03-28 16:26:41 +02001991 if (lnum <= 0 && argvars[0].v_type != VAR_NUMBER)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001992 {
1993 int fnum;
Bram Moolenaar6f02b002021-01-10 20:22:54 +01001994 pos_T *fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001995
Bram Moolenaarf6bdd822021-03-28 16:26:41 +02001996 // no valid number, try using arg like line()
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001997 if (fp != NULL)
1998 lnum = fp->lnum;
1999 }
2000 return lnum;
2001}
2002
2003/*
2004 * Get the lnum from the first argument.
2005 * Also accepts "$", then "buf" is used.
2006 * Returns 0 on error.
2007 */
2008 linenr_T
2009tv_get_lnum_buf(typval_T *argvars, buf_T *buf)
2010{
2011 if (argvars[0].v_type == VAR_STRING
2012 && argvars[0].vval.v_string != NULL
2013 && argvars[0].vval.v_string[0] == '$'
2014 && buf != NULL)
2015 return buf->b_ml.ml_line_count;
2016 return (linenr_T)tv_get_number_chk(&argvars[0], NULL);
2017}
2018
2019/*
2020 * Get buffer by number or pattern.
2021 */
2022 buf_T *
2023tv_get_buf(typval_T *tv, int curtab_only)
2024{
2025 char_u *name = tv->vval.v_string;
2026 buf_T *buf;
2027
2028 if (tv->v_type == VAR_NUMBER)
2029 return buflist_findnr((int)tv->vval.v_number);
2030 if (tv->v_type != VAR_STRING)
2031 return NULL;
2032 if (name == NULL || *name == NUL)
2033 return curbuf;
2034 if (name[0] == '$' && name[1] == NUL)
2035 return lastbuf;
2036
2037 buf = buflist_find_by_name(name, curtab_only);
2038
2039 // If not found, try expanding the name, like done for bufexists().
2040 if (buf == NULL)
2041 buf = find_buffer(tv);
2042
2043 return buf;
2044}
2045
Bram Moolenaar3767e3a2020-09-01 23:06:01 +02002046/*
2047 * Like tv_get_buf() but give an error message is the type is wrong.
2048 */
2049 buf_T *
2050tv_get_buf_from_arg(typval_T *tv)
2051{
2052 buf_T *buf;
2053
2054 ++emsg_off;
2055 buf = tv_get_buf(tv, FALSE);
2056 --emsg_off;
2057 if (buf == NULL
2058 && tv->v_type != VAR_NUMBER
2059 && tv->v_type != VAR_STRING)
2060 // issue errmsg for type error
2061 (void)tv_get_number(tv);
2062 return buf;
2063}
2064
Bram Moolenaar367d59e2020-05-30 17:06:14 +02002065#endif // FEAT_EVAL