blob: 29c925d66e32f3122f881ca8b2c21c2fda8c8488 [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 Lakshmanana9a7c0c2021-07-17 19:11:07 +0200425 * Give an error and return FAIL unless "args[idx]" is a bool.
426 */
427 int
428check_for_bool_arg(typval_T *args, int idx)
429{
430 if (args[idx].v_type != VAR_BOOL
431 && !(args[idx].v_type == VAR_NUMBER
432 && (args[idx].vval.v_number == 0
433 || args[idx].vval.v_number == 1)))
434 {
435 if (idx >= 0)
436 semsg(_(e_bool_required_for_argument_nr), idx + 1);
437 else
438 emsg(_(e_boolreq));
439 return FAIL;
440 }
441 return OK;
442}
443
444/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200445 * Check for an optional bool argument at 'idx'
446 */
447 int
448check_for_opt_bool_arg(typval_T *args, int idx)
449{
450 return (args[idx].v_type == VAR_UNKNOWN
451 || check_for_bool_arg(args, idx) != FAIL);
452}
453
454/*
Yegappan Lakshmanana9a7c0c2021-07-17 19:11:07 +0200455 * Give an error and return FAIL unless "args[idx]" is a list.
456 */
457 int
458check_for_list_arg(typval_T *args, int idx)
459{
460 if (args[idx].v_type != VAR_LIST)
461 {
462 if (idx >= 0)
463 semsg(_(e_list_required_for_argument_nr), idx + 1);
464 else
465 emsg(_(e_listreq));
466 return FAIL;
467 }
468 return OK;
469}
470
471/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200472 * Check for an optional list argument at 'idx'
473 */
474 int
475check_for_opt_list_arg(typval_T *args, int idx)
476{
477 return (args[idx].v_type == VAR_UNKNOWN
478 || check_for_list_arg(args, idx) != FAIL);
479}
480
481/*
Yegappan Lakshmanana9a7c0c2021-07-17 19:11:07 +0200482 * Give an error and return FAIL unless "args[idx]" is a dict.
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200483 */
484 int
485check_for_dict_arg(typval_T *args, int idx)
486{
487 if (args[idx].v_type != VAR_DICT)
488 {
489 if (idx >= 0)
490 semsg(_(e_dict_required_for_argument_nr), idx + 1);
491 else
492 emsg(_(e_dictreq));
493 return FAIL;
494 }
495 return OK;
496}
497
498/*
Yegappan Lakshmanan83494b42021-07-20 17:51:51 +0200499 * Check for an optional dict argument at 'idx'
500 */
501 int
502check_for_opt_dict_arg(typval_T *args, int idx)
503{
504 return (args[idx].v_type == VAR_UNKNOWN
505 || check_for_dict_arg(args, idx) != FAIL);
506}
507
508/*
509 * Give an error and return FAIL unless "args[idx]" is a blob.
510 */
511 int
512check_for_blob_arg(typval_T *args, int idx)
513{
514 if (args[idx].v_type != VAR_BLOB)
515 {
516 if (idx >= 0)
517 semsg(_(e_blob_required_for_argument_nr), idx + 1);
518 else
519 emsg(_(e_blobreq));
520 return FAIL;
521 }
522 return OK;
523}
524
525/*
526 * 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/*
543 * Give an error and return FAIL unless "args[idx]" is a job.
544 */
545 int
546check_for_job_arg(typval_T *args, int idx)
547{
548 if (args[idx].v_type != VAR_JOB)
549 {
550 if (idx >= 0)
551 semsg(_(e_job_required_for_argument_nr), idx + 1);
552 else
553 emsg(_(e_jobreq));
554 return FAIL;
555 }
556 return OK;
557}
558
559/*
560 * Give an error and return FAIL unless "args[idx]" is a string or
561 * a number.
562 */
563 int
564check_for_string_or_number_arg(typval_T *args, int idx)
565{
566 if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
567 {
568 if (idx >= 0)
569 semsg(_(e_string_required_for_argument_nr), idx + 1);
570 else
571 emsg(_(e_stringreq));
572 return FAIL;
573 }
574 return OK;
575}
576
577/*
578 * Give an error and return FAIL unless "args[idx]" is a string or
579 * a number (buffer)
580 */
581 int
582check_for_buffer_arg(typval_T *args, int idx)
583{
584 if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
585 {
586 if (idx >= 0)
587 semsg(_(e_string_required_for_argument_nr), idx + 1);
588 else
589 emsg(_(e_stringreq));
590 return FAIL;
591 }
592 return OK;
593}
594
595/*
596 * Give an error and return FAIL unless "args[idx]" is a string or
597 * a number (line)
598 */
599 int
600check_for_lnum_arg(typval_T *args, int idx)
601{
602 if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
603 {
604 if (idx >= 0)
605 semsg(_(e_string_required_for_argument_nr), idx + 1);
606 else
607 emsg(_(e_stringreq));
608 return FAIL;
609 }
610 return OK;
611}
612
613/*
614 * Give an error and return FAIL unless "args[idx]" is a string or
615 * a number (line)
616 */
617 int
618check_for_opt_lnum_arg(typval_T *args, int idx)
619{
620 if (args[idx].v_type != VAR_UNKNOWN
621 && args[idx].v_type != VAR_STRING
622 && args[idx].v_type != VAR_NUMBER)
623 {
624 if (idx >= 0)
625 semsg(_(e_string_required_for_argument_nr), idx + 1);
626 else
627 emsg(_(e_stringreq));
628 return FAIL;
629 }
630 return OK;
631}
632
633/*
634 * Check for an optional string or number argument at 'idx'
635 */
636 int
637check_for_opt_string_or_number_arg(typval_T *args, int idx)
638{
639 return (args[idx].v_type == VAR_UNKNOWN
640 || check_for_string_or_number_arg(args, idx) != FAIL);
641}
642
643/*
644 * Give an error and return FAIL unless "args[idx]" is a string or
645 * a blob.
646 */
647 int
648check_for_string_or_blob_arg(typval_T *args, int idx)
649{
650 if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_BLOB)
651 {
652 if (idx >= 0)
653 semsg(_(e_string_required_for_argument_nr), idx + 1);
654 else
655 emsg(_(e_stringreq));
656 return FAIL;
657 }
658 return OK;
659}
660
661/*
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200662 * Get the string value of a variable.
663 * If it is a Number variable, the number is converted into a string.
664 * tv_get_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
665 * tv_get_string_buf() uses a given buffer.
666 * If the String variable has never been set, return an empty string.
667 * Never returns NULL;
668 * tv_get_string_chk() and tv_get_string_buf_chk() are similar, but return
669 * NULL on error.
670 */
671 char_u *
672tv_get_string(typval_T *varp)
673{
674 static char_u mybuf[NUMBUFLEN];
675
676 return tv_get_string_buf(varp, mybuf);
677}
678
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100679/*
680 * Like tv_get_string() but don't allow number to string conversion for Vim9.
681 */
682 char_u *
683tv_get_string_strict(typval_T *varp)
684{
685 static char_u mybuf[NUMBUFLEN];
686 char_u *res = tv_get_string_buf_chk_strict(
687 varp, mybuf, in_vim9script());
688
689 return res != NULL ? res : (char_u *)"";
690}
691
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200692 char_u *
693tv_get_string_buf(typval_T *varp, char_u *buf)
694{
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200695 char_u *res = tv_get_string_buf_chk(varp, buf);
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200696
697 return res != NULL ? res : (char_u *)"";
698}
699
700/*
701 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
702 */
703 char_u *
704tv_get_string_chk(typval_T *varp)
705{
706 static char_u mybuf[NUMBUFLEN];
707
708 return tv_get_string_buf_chk(varp, mybuf);
709}
710
711 char_u *
712tv_get_string_buf_chk(typval_T *varp, char_u *buf)
713{
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100714 return tv_get_string_buf_chk_strict(varp, buf, FALSE);
715}
716
717 char_u *
718tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
719{
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200720 switch (varp->v_type)
721 {
722 case VAR_NUMBER:
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100723 if (strict)
724 {
725 emsg(_(e_using_number_as_string));
726 break;
727 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200728 vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
729 (varnumber_T)varp->vval.v_number);
730 return buf;
731 case VAR_FUNC:
732 case VAR_PARTIAL:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200733 emsg(_("E729: Using a Funcref as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200734 break;
735 case VAR_LIST:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200736 emsg(_("E730: Using a List as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200737 break;
738 case VAR_DICT:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200739 emsg(_("E731: Using a Dictionary as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200740 break;
741 case VAR_FLOAT:
742#ifdef FEAT_FLOAT
Bram Moolenaar7a2217b2021-06-06 12:33:49 +0200743 if (strict)
744 {
745 emsg(_(e_float_as_string));
746 break;
747 }
748 vim_snprintf((char *)buf, NUMBUFLEN, "%g", varp->vval.v_float);
749 return buf;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200750#endif
751 case VAR_STRING:
752 if (varp->vval.v_string != NULL)
753 return varp->vval.v_string;
754 return (char_u *)"";
755 case VAR_BOOL:
756 case VAR_SPECIAL:
757 STRCPY(buf, get_var_special_name(varp->vval.v_number));
758 return buf;
759 case VAR_BLOB:
Yegappan Lakshmanan5b739922021-07-10 13:15:41 +0200760 emsg(_("E976: Using a Blob as a String"));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200761 break;
762 case VAR_JOB:
763#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200764 if (in_vim9script())
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200765 {
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200766 semsg(_(e_using_invalid_value_as_string_str), "job");
767 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200768 }
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200769 return job_to_string_buf(varp, buf);
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200770#endif
771 break;
772 case VAR_CHANNEL:
773#ifdef FEAT_JOB_CHANNEL
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200774 if (in_vim9script())
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200775 {
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200776 semsg(_(e_using_invalid_value_as_string_str), "channel");
777 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200778 }
Bram Moolenaar1328bde2021-06-05 20:51:38 +0200779 return channel_to_string_buf(varp, buf);
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200780#endif
781 break;
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200782 case VAR_VOID:
783 emsg(_(e_cannot_use_void_value));
784 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200785 case VAR_UNKNOWN:
786 case VAR_ANY:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200787 case VAR_INSTR:
Bram Moolenaar68db9962021-05-09 23:19:22 +0200788 semsg(_(e_using_invalid_value_as_string_str),
789 vartype_name(varp->v_type));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200790 break;
791 }
792 return NULL;
793}
794
795/*
796 * Turn a typeval into a string. Similar to tv_get_string_buf() but uses
797 * string() on Dict, List, etc.
798 */
799 char_u *
800tv_stringify(typval_T *varp, char_u *buf)
801{
802 if (varp->v_type == VAR_LIST
803 || varp->v_type == VAR_DICT
804 || varp->v_type == VAR_BLOB
805 || varp->v_type == VAR_FUNC
806 || varp->v_type == VAR_PARTIAL
807 || varp->v_type == VAR_FLOAT)
808 {
809 typval_T tmp;
810
811 f_string(varp, &tmp);
812 tv_get_string_buf(&tmp, buf);
813 clear_tv(varp);
814 *varp = tmp;
815 return tmp.vval.v_string;
816 }
817 return tv_get_string_buf(varp, buf);
818}
819
820/*
821 * Return TRUE if typeval "tv" and its value are set to be locked (immutable).
822 * Also give an error message, using "name" or _("name") when use_gettext is
823 * TRUE.
824 */
825 int
826tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
827{
828 int lock = 0;
829
830 switch (tv->v_type)
831 {
832 case VAR_BLOB:
833 if (tv->vval.v_blob != NULL)
834 lock = tv->vval.v_blob->bv_lock;
835 break;
836 case VAR_LIST:
837 if (tv->vval.v_list != NULL)
838 lock = tv->vval.v_list->lv_lock;
839 break;
840 case VAR_DICT:
841 if (tv->vval.v_dict != NULL)
842 lock = tv->vval.v_dict->dv_lock;
843 break;
844 default:
845 break;
846 }
Bram Moolenaara187c432020-09-16 21:08:28 +0200847 return value_check_lock(tv->v_lock, name, use_gettext)
848 || (lock != 0 && value_check_lock(lock, name, use_gettext));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200849}
850
851/*
852 * Copy the values from typval_T "from" to typval_T "to".
853 * When needed allocates string or increases reference count.
854 * Does not make a copy of a list, blob or dict but copies the reference!
855 * It is OK for "from" and "to" to point to the same item. This is used to
856 * make a copy later.
857 */
858 void
859copy_tv(typval_T *from, typval_T *to)
860{
861 to->v_type = from->v_type;
862 to->v_lock = 0;
863 switch (from->v_type)
864 {
865 case VAR_NUMBER:
866 case VAR_BOOL:
867 case VAR_SPECIAL:
868 to->vval.v_number = from->vval.v_number;
869 break;
870 case VAR_FLOAT:
871#ifdef FEAT_FLOAT
872 to->vval.v_float = from->vval.v_float;
873 break;
874#endif
875 case VAR_JOB:
876#ifdef FEAT_JOB_CHANNEL
877 to->vval.v_job = from->vval.v_job;
878 if (to->vval.v_job != NULL)
879 ++to->vval.v_job->jv_refcount;
880 break;
881#endif
882 case VAR_CHANNEL:
883#ifdef FEAT_JOB_CHANNEL
884 to->vval.v_channel = from->vval.v_channel;
885 if (to->vval.v_channel != NULL)
886 ++to->vval.v_channel->ch_refcount;
887 break;
888#endif
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200889 case VAR_INSTR:
890 to->vval.v_instr = from->vval.v_instr;
891 break;
892
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200893 case VAR_STRING:
894 case VAR_FUNC:
895 if (from->vval.v_string == NULL)
896 to->vval.v_string = NULL;
897 else
898 {
899 to->vval.v_string = vim_strsave(from->vval.v_string);
900 if (from->v_type == VAR_FUNC)
901 func_ref(to->vval.v_string);
902 }
903 break;
904 case VAR_PARTIAL:
905 if (from->vval.v_partial == NULL)
906 to->vval.v_partial = NULL;
907 else
908 {
909 to->vval.v_partial = from->vval.v_partial;
910 ++to->vval.v_partial->pt_refcount;
911 }
912 break;
913 case VAR_BLOB:
914 if (from->vval.v_blob == NULL)
915 to->vval.v_blob = NULL;
916 else
917 {
918 to->vval.v_blob = from->vval.v_blob;
919 ++to->vval.v_blob->bv_refcount;
920 }
921 break;
922 case VAR_LIST:
923 if (from->vval.v_list == NULL)
924 to->vval.v_list = NULL;
925 else
926 {
927 to->vval.v_list = from->vval.v_list;
928 ++to->vval.v_list->lv_refcount;
929 }
930 break;
931 case VAR_DICT:
932 if (from->vval.v_dict == NULL)
933 to->vval.v_dict = NULL;
934 else
935 {
936 to->vval.v_dict = from->vval.v_dict;
937 ++to->vval.v_dict->dv_refcount;
938 }
939 break;
Bram Moolenaar61a417b2021-06-15 22:54:28 +0200940 case VAR_VOID:
941 emsg(_(e_cannot_use_void_value));
942 break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200943 case VAR_UNKNOWN:
944 case VAR_ANY:
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200945 internal_error_no_abort("copy_tv(UNKNOWN)");
946 break;
947 }
948}
949
950/*
951 * Compare "typ1" and "typ2". Put the result in "typ1".
952 */
953 int
954typval_compare(
955 typval_T *typ1, // first operand
956 typval_T *typ2, // second operand
Bram Moolenaar657137c2021-01-09 15:45:23 +0100957 exprtype_T type, // operator
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200958 int ic) // ignore case
959{
960 int i;
961 varnumber_T n1, n2;
962 char_u *s1, *s2;
963 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
964 int type_is = type == EXPR_IS || type == EXPR_ISNOT;
965
966 if (type_is && typ1->v_type != typ2->v_type)
967 {
968 // For "is" a different type always means FALSE, for "notis"
969 // it means TRUE.
970 n1 = (type == EXPR_ISNOT);
971 }
972 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
973 {
974 if (type_is)
975 {
976 n1 = (typ1->v_type == typ2->v_type
977 && typ1->vval.v_blob == typ2->vval.v_blob);
978 if (type == EXPR_ISNOT)
979 n1 = !n1;
980 }
981 else if (typ1->v_type != typ2->v_type
982 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
983 {
984 if (typ1->v_type != typ2->v_type)
985 emsg(_("E977: Can only compare Blob with Blob"));
986 else
987 emsg(_(e_invalblob));
988 clear_tv(typ1);
989 return FAIL;
990 }
991 else
992 {
993 // Compare two Blobs for being equal or unequal.
994 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
995 if (type == EXPR_NEQUAL)
996 n1 = !n1;
997 }
998 }
999 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
1000 {
1001 if (type_is)
1002 {
1003 n1 = (typ1->v_type == typ2->v_type
1004 && typ1->vval.v_list == typ2->vval.v_list);
1005 if (type == EXPR_ISNOT)
1006 n1 = !n1;
1007 }
1008 else if (typ1->v_type != typ2->v_type
1009 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1010 {
1011 if (typ1->v_type != typ2->v_type)
1012 emsg(_("E691: Can only compare List with List"));
1013 else
1014 emsg(_("E692: Invalid operation for List"));
1015 clear_tv(typ1);
1016 return FAIL;
1017 }
1018 else
1019 {
1020 // Compare two Lists for being equal or unequal.
1021 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
1022 ic, FALSE);
1023 if (type == EXPR_NEQUAL)
1024 n1 = !n1;
1025 }
1026 }
1027
1028 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
1029 {
1030 if (type_is)
1031 {
1032 n1 = (typ1->v_type == typ2->v_type
1033 && typ1->vval.v_dict == typ2->vval.v_dict);
1034 if (type == EXPR_ISNOT)
1035 n1 = !n1;
1036 }
1037 else if (typ1->v_type != typ2->v_type
1038 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1039 {
1040 if (typ1->v_type != typ2->v_type)
1041 emsg(_("E735: Can only compare Dictionary with Dictionary"));
1042 else
1043 emsg(_("E736: Invalid operation for Dictionary"));
1044 clear_tv(typ1);
1045 return FAIL;
1046 }
1047 else
1048 {
1049 // Compare two Dictionaries for being equal or unequal.
1050 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
1051 ic, FALSE);
1052 if (type == EXPR_NEQUAL)
1053 n1 = !n1;
1054 }
1055 }
1056
1057 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
1058 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
1059 {
1060 if (type != EXPR_EQUAL && type != EXPR_NEQUAL
1061 && type != EXPR_IS && type != EXPR_ISNOT)
1062 {
1063 emsg(_("E694: Invalid operation for Funcrefs"));
1064 clear_tv(typ1);
1065 return FAIL;
1066 }
1067 if ((typ1->v_type == VAR_PARTIAL
1068 && typ1->vval.v_partial == NULL)
1069 || (typ2->v_type == VAR_PARTIAL
1070 && typ2->vval.v_partial == NULL))
1071 // When both partials are NULL, then they are equal.
1072 // Otherwise they are not equal.
1073 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
1074 else if (type_is)
1075 {
1076 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
1077 // strings are considered the same if their value is
1078 // the same
1079 n1 = tv_equal(typ1, typ2, ic, FALSE);
1080 else if (typ1->v_type == VAR_PARTIAL
1081 && typ2->v_type == VAR_PARTIAL)
1082 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
1083 else
1084 n1 = FALSE;
1085 }
1086 else
1087 n1 = tv_equal(typ1, typ2, ic, FALSE);
1088 if (type == EXPR_NEQUAL || type == EXPR_ISNOT)
1089 n1 = !n1;
1090 }
1091
1092#ifdef FEAT_FLOAT
1093 // If one of the two variables is a float, compare as a float.
1094 // When using "=~" or "!~", always compare as string.
1095 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
1096 && type != EXPR_MATCH && type != EXPR_NOMATCH)
1097 {
1098 float_T f1, f2;
1099
1100 f1 = tv_get_float(typ1);
1101 f2 = tv_get_float(typ2);
1102 n1 = FALSE;
1103 switch (type)
1104 {
1105 case EXPR_IS:
1106 case EXPR_EQUAL: n1 = (f1 == f2); break;
1107 case EXPR_ISNOT:
1108 case EXPR_NEQUAL: n1 = (f1 != f2); break;
1109 case EXPR_GREATER: n1 = (f1 > f2); break;
1110 case EXPR_GEQUAL: n1 = (f1 >= f2); break;
1111 case EXPR_SMALLER: n1 = (f1 < f2); break;
1112 case EXPR_SEQUAL: n1 = (f1 <= f2); break;
1113 case EXPR_UNKNOWN:
1114 case EXPR_MATCH:
1115 default: break; // avoid gcc warning
1116 }
1117 }
1118#endif
1119
1120 // If one of the two variables is a number, compare as a number.
1121 // When using "=~" or "!~", always compare as string.
1122 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
1123 && type != EXPR_MATCH && type != EXPR_NOMATCH)
1124 {
1125 n1 = tv_get_number(typ1);
1126 n2 = tv_get_number(typ2);
1127 switch (type)
1128 {
1129 case EXPR_IS:
1130 case EXPR_EQUAL: n1 = (n1 == n2); break;
1131 case EXPR_ISNOT:
1132 case EXPR_NEQUAL: n1 = (n1 != n2); break;
1133 case EXPR_GREATER: n1 = (n1 > n2); break;
1134 case EXPR_GEQUAL: n1 = (n1 >= n2); break;
1135 case EXPR_SMALLER: n1 = (n1 < n2); break;
1136 case EXPR_SEQUAL: n1 = (n1 <= n2); break;
1137 case EXPR_UNKNOWN:
1138 case EXPR_MATCH:
1139 default: break; // avoid gcc warning
1140 }
1141 }
Bram Moolenaarcff40ff2021-01-09 16:21:37 +01001142 else if (in_vim9script() && (typ1->v_type == VAR_BOOL
Bram Moolenaar0c357522021-07-18 14:43:43 +02001143 || typ2->v_type == VAR_BOOL
1144 || (typ1->v_type == VAR_SPECIAL
1145 && typ2->v_type == VAR_SPECIAL)))
Bram Moolenaarcff40ff2021-01-09 16:21:37 +01001146 {
1147 if (typ1->v_type != typ2->v_type)
1148 {
1149 semsg(_(e_cannot_compare_str_with_str),
1150 vartype_name(typ1->v_type), vartype_name(typ2->v_type));
1151 clear_tv(typ1);
1152 return FAIL;
1153 }
1154 n1 = typ1->vval.v_number;
1155 n2 = typ2->vval.v_number;
1156 switch (type)
1157 {
1158 case EXPR_IS:
1159 case EXPR_EQUAL: n1 = (n1 == n2); break;
1160 case EXPR_ISNOT:
1161 case EXPR_NEQUAL: n1 = (n1 != n2); break;
1162 default:
Bram Moolenaar0c357522021-07-18 14:43:43 +02001163 semsg(_(e_invalid_operation_for_str),
1164 vartype_name(typ1->v_type));
Bram Moolenaarcff40ff2021-01-09 16:21:37 +01001165 clear_tv(typ1);
1166 return FAIL;
1167 }
1168 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001169 else
1170 {
Bram Moolenaar0c357522021-07-18 14:43:43 +02001171 if (in_vim9script()
1172 && ((typ1->v_type != VAR_STRING && typ1->v_type != VAR_SPECIAL)
1173 || (typ2->v_type != VAR_STRING && typ2->v_type != VAR_SPECIAL)))
1174 {
1175 semsg(_(e_cannot_compare_str_with_str),
1176 vartype_name(typ1->v_type), vartype_name(typ2->v_type));
1177 clear_tv(typ1);
1178 return FAIL;
1179 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001180 s1 = tv_get_string_buf(typ1, buf1);
1181 s2 = tv_get_string_buf(typ2, buf2);
1182 if (type != EXPR_MATCH && type != EXPR_NOMATCH)
1183 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
1184 else
1185 i = 0;
1186 n1 = FALSE;
1187 switch (type)
1188 {
1189 case EXPR_IS:
1190 case EXPR_EQUAL: n1 = (i == 0); break;
1191 case EXPR_ISNOT:
1192 case EXPR_NEQUAL: n1 = (i != 0); break;
1193 case EXPR_GREATER: n1 = (i > 0); break;
1194 case EXPR_GEQUAL: n1 = (i >= 0); break;
1195 case EXPR_SMALLER: n1 = (i < 0); break;
1196 case EXPR_SEQUAL: n1 = (i <= 0); break;
1197
1198 case EXPR_MATCH:
1199 case EXPR_NOMATCH:
1200 n1 = pattern_match(s2, s1, ic);
1201 if (type == EXPR_NOMATCH)
1202 n1 = !n1;
1203 break;
1204
1205 default: break; // avoid gcc warning
1206 }
1207 }
1208 clear_tv(typ1);
Bram Moolenaarc71f36a2020-07-21 21:31:00 +02001209 if (in_vim9script())
1210 {
1211 typ1->v_type = VAR_BOOL;
1212 typ1->vval.v_number = n1 ? VVAL_TRUE : VVAL_FALSE;
1213 }
1214 else
1215 {
1216 typ1->v_type = VAR_NUMBER;
1217 typ1->vval.v_number = n1;
1218 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001219
1220 return OK;
1221}
1222
Bram Moolenaar34453202021-01-31 13:08:38 +01001223/*
1224 * Convert any type to a string, never give an error.
1225 * When "quotes" is TRUE add quotes to a string.
1226 * Returns an allocated string.
1227 */
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001228 char_u *
Bram Moolenaar34453202021-01-31 13:08:38 +01001229typval_tostring(typval_T *arg, int quotes)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001230{
1231 char_u *tofree;
1232 char_u numbuf[NUMBUFLEN];
1233 char_u *ret = NULL;
1234
1235 if (arg == NULL)
1236 return vim_strsave((char_u *)"(does not exist)");
Bram Moolenaar34453202021-01-31 13:08:38 +01001237 if (!quotes && arg->v_type == VAR_STRING)
1238 {
1239 ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
1240 : arg->vval.v_string);
1241 }
1242 else
1243 {
1244 ret = tv2string(arg, &tofree, numbuf, 0);
1245 // Make a copy if we have a value but it's not in allocated memory.
1246 if (ret != NULL && tofree == NULL)
1247 ret = vim_strsave(ret);
1248 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001249 return ret;
1250}
1251
1252/*
1253 * Return TRUE if typeval "tv" is locked: Either that value is locked itself
1254 * or it refers to a List or Dictionary that is locked.
1255 */
1256 int
1257tv_islocked(typval_T *tv)
1258{
1259 return (tv->v_lock & VAR_LOCKED)
1260 || (tv->v_type == VAR_LIST
1261 && tv->vval.v_list != NULL
1262 && (tv->vval.v_list->lv_lock & VAR_LOCKED))
1263 || (tv->v_type == VAR_DICT
1264 && tv->vval.v_dict != NULL
1265 && (tv->vval.v_dict->dv_lock & VAR_LOCKED));
1266}
1267
1268 static int
1269func_equal(
1270 typval_T *tv1,
1271 typval_T *tv2,
1272 int ic) // ignore case
1273{
1274 char_u *s1, *s2;
1275 dict_T *d1, *d2;
1276 int a1, a2;
1277 int i;
1278
1279 // empty and NULL function name considered the same
1280 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
1281 : partial_name(tv1->vval.v_partial);
1282 if (s1 != NULL && *s1 == NUL)
1283 s1 = NULL;
1284 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
1285 : partial_name(tv2->vval.v_partial);
1286 if (s2 != NULL && *s2 == NUL)
1287 s2 = NULL;
1288 if (s1 == NULL || s2 == NULL)
1289 {
1290 if (s1 != s2)
1291 return FALSE;
1292 }
1293 else if (STRCMP(s1, s2) != 0)
1294 return FALSE;
1295
1296 // empty dict and NULL dict is different
1297 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
1298 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
1299 if (d1 == NULL || d2 == NULL)
1300 {
1301 if (d1 != d2)
1302 return FALSE;
1303 }
1304 else if (!dict_equal(d1, d2, ic, TRUE))
1305 return FALSE;
1306
1307 // empty list and no list considered the same
1308 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
1309 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
1310 if (a1 != a2)
1311 return FALSE;
1312 for (i = 0; i < a1; ++i)
1313 if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
1314 tv2->vval.v_partial->pt_argv + i, ic, TRUE))
1315 return FALSE;
1316
1317 return TRUE;
1318}
1319
1320/*
1321 * Return TRUE if "tv1" and "tv2" have the same value.
1322 * Compares the items just like "==" would compare them, but strings and
1323 * numbers are different. Floats and numbers are also different.
1324 */
1325 int
1326tv_equal(
1327 typval_T *tv1,
1328 typval_T *tv2,
1329 int ic, // ignore case
1330 int recursive) // TRUE when used recursively
1331{
1332 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1333 char_u *s1, *s2;
1334 static int recursive_cnt = 0; // catch recursive loops
1335 int r;
1336 static int tv_equal_recurse_limit;
1337
1338 // Catch lists and dicts that have an endless loop by limiting
1339 // recursiveness to a limit. We guess they are equal then.
1340 // A fixed limit has the problem of still taking an awful long time.
1341 // Reduce the limit every time running into it. That should work fine for
1342 // deeply linked structures that are not recursively linked and catch
1343 // recursiveness quickly.
1344 if (!recursive)
1345 tv_equal_recurse_limit = 1000;
1346 if (recursive_cnt >= tv_equal_recurse_limit)
1347 {
1348 --tv_equal_recurse_limit;
1349 return TRUE;
1350 }
1351
1352 // For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and
1353 // arguments.
1354 if ((tv1->v_type == VAR_FUNC
1355 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
1356 && (tv2->v_type == VAR_FUNC
1357 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
1358 {
1359 ++recursive_cnt;
1360 r = func_equal(tv1, tv2, ic);
1361 --recursive_cnt;
1362 return r;
1363 }
1364
Bram Moolenaar418a29f2021-02-10 22:23:41 +01001365 if (tv1->v_type != tv2->v_type
1366 && ((tv1->v_type != VAR_BOOL && tv1->v_type != VAR_SPECIAL)
1367 || (tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL)))
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001368 return FALSE;
1369
1370 switch (tv1->v_type)
1371 {
1372 case VAR_LIST:
1373 ++recursive_cnt;
1374 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
1375 --recursive_cnt;
1376 return r;
1377
1378 case VAR_DICT:
1379 ++recursive_cnt;
1380 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
1381 --recursive_cnt;
1382 return r;
1383
1384 case VAR_BLOB:
1385 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
1386
1387 case VAR_NUMBER:
1388 case VAR_BOOL:
1389 case VAR_SPECIAL:
1390 return tv1->vval.v_number == tv2->vval.v_number;
1391
1392 case VAR_STRING:
1393 s1 = tv_get_string_buf(tv1, buf1);
1394 s2 = tv_get_string_buf(tv2, buf2);
1395 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
1396
1397 case VAR_FLOAT:
1398#ifdef FEAT_FLOAT
1399 return tv1->vval.v_float == tv2->vval.v_float;
1400#endif
1401 case VAR_JOB:
1402#ifdef FEAT_JOB_CHANNEL
1403 return tv1->vval.v_job == tv2->vval.v_job;
1404#endif
1405 case VAR_CHANNEL:
1406#ifdef FEAT_JOB_CHANNEL
1407 return tv1->vval.v_channel == tv2->vval.v_channel;
1408#endif
Bram Moolenaarf18332f2021-05-07 17:55:55 +02001409 case VAR_INSTR:
1410 return tv1->vval.v_instr == tv2->vval.v_instr;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001411
1412 case VAR_PARTIAL:
1413 return tv1->vval.v_partial == tv2->vval.v_partial;
1414
1415 case VAR_FUNC:
1416 return tv1->vval.v_string == tv2->vval.v_string;
1417
1418 case VAR_UNKNOWN:
1419 case VAR_ANY:
1420 case VAR_VOID:
1421 break;
1422 }
1423
1424 // VAR_UNKNOWN can be the result of a invalid expression, let's say it
1425 // does not equal anything, not even itself.
1426 return FALSE;
1427}
1428
1429/*
1430 * Get an option value.
1431 * "arg" points to the '&' or '+' before the option name.
1432 * "arg" is advanced to character after the option name.
1433 * Return OK or FAIL.
1434 */
1435 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001436eval_option(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001437 char_u **arg,
1438 typval_T *rettv, // when NULL, only check if option exists
1439 int evaluate)
1440{
1441 char_u *option_end;
1442 long numval;
1443 char_u *stringval;
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001444 getoption_T opt_type;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001445 int c;
1446 int working = (**arg == '+'); // has("+option")
1447 int ret = OK;
1448 int opt_flags;
1449
1450 // Isolate the option name and find its value.
1451 option_end = find_option_end(arg, &opt_flags);
1452 if (option_end == NULL)
1453 {
1454 if (rettv != NULL)
1455 semsg(_("E112: Option name missing: %s"), *arg);
1456 return FAIL;
1457 }
1458
1459 if (!evaluate)
1460 {
1461 *arg = option_end;
1462 return OK;
1463 }
1464
1465 c = *option_end;
1466 *option_end = NUL;
1467 opt_type = get_option_value(*arg, &numval,
1468 rettv == NULL ? NULL : &stringval, opt_flags);
1469
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001470 if (opt_type == gov_unknown)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001471 {
1472 if (rettv != NULL)
1473 semsg(_(e_unknown_option), *arg);
1474 ret = FAIL;
1475 }
1476 else if (rettv != NULL)
1477 {
Bram Moolenaara79925a2021-01-05 17:50:28 +01001478 rettv->v_lock = 0;
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001479 if (opt_type == gov_hidden_string)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001480 {
1481 rettv->v_type = VAR_STRING;
1482 rettv->vval.v_string = NULL;
1483 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001484 else if (opt_type == gov_hidden_bool || opt_type == gov_hidden_number)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001485 {
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001486 rettv->v_type = in_vim9script() && opt_type == gov_hidden_bool
1487 ? VAR_BOOL : VAR_NUMBER;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001488 rettv->vval.v_number = 0;
1489 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001490 else if (opt_type == gov_bool || opt_type == gov_number)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001491 {
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001492 if (in_vim9script() && opt_type == gov_bool)
1493 {
1494 rettv->v_type = VAR_BOOL;
1495 rettv->vval.v_number = numval ? VVAL_TRUE : VVAL_FALSE;
1496 }
1497 else
1498 {
1499 rettv->v_type = VAR_NUMBER;
1500 rettv->vval.v_number = numval;
1501 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001502 }
1503 else // string option
1504 {
1505 rettv->v_type = VAR_STRING;
1506 rettv->vval.v_string = stringval;
1507 }
1508 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001509 else if (working && (opt_type == gov_hidden_bool
1510 || opt_type == gov_hidden_number
1511 || opt_type == gov_hidden_string))
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001512 ret = FAIL;
1513
1514 *option_end = c; // put back for error messages
1515 *arg = option_end;
1516
1517 return ret;
1518}
1519
1520/*
1521 * Allocate a variable for a number constant. Also deals with "0z" for blob.
1522 * Return OK or FAIL.
1523 */
1524 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001525eval_number(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001526 char_u **arg,
1527 typval_T *rettv,
1528 int evaluate,
1529 int want_string UNUSED)
1530{
1531 int len;
1532#ifdef FEAT_FLOAT
1533 char_u *p;
1534 int get_float = FALSE;
1535
1536 // We accept a float when the format matches
1537 // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
1538 // strict to avoid backwards compatibility problems.
1539 // With script version 2 and later the leading digit can be
1540 // omitted.
1541 // Don't look for a float after the "." operator, so that
1542 // ":let vers = 1.2.3" doesn't fail.
1543 if (**arg == '.')
1544 p = *arg;
1545 else
1546 p = skipdigits(*arg + 1);
1547 if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
1548 {
1549 get_float = TRUE;
1550 p = skipdigits(p + 2);
1551 if (*p == 'e' || *p == 'E')
1552 {
1553 ++p;
1554 if (*p == '-' || *p == '+')
1555 ++p;
1556 if (!vim_isdigit(*p))
1557 get_float = FALSE;
1558 else
1559 p = skipdigits(p + 1);
1560 }
1561 if (ASCII_ISALPHA(*p) || *p == '.')
1562 get_float = FALSE;
1563 }
1564 if (get_float)
1565 {
1566 float_T f;
1567
1568 *arg += string2float(*arg, &f);
1569 if (evaluate)
1570 {
1571 rettv->v_type = VAR_FLOAT;
1572 rettv->vval.v_float = f;
1573 }
1574 }
1575 else
1576#endif
1577 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
1578 {
1579 char_u *bp;
1580 blob_T *blob = NULL; // init for gcc
1581
1582 // Blob constant: 0z0123456789abcdef
1583 if (evaluate)
1584 blob = blob_alloc();
1585 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
1586 {
1587 if (!vim_isxdigit(bp[1]))
1588 {
1589 if (blob != NULL)
1590 {
1591 emsg(_("E973: Blob literal should have an even number of hex characters"));
1592 ga_clear(&blob->bv_ga);
1593 VIM_CLEAR(blob);
1594 }
1595 return FAIL;
1596 }
1597 if (blob != NULL)
1598 ga_append(&blob->bv_ga,
1599 (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
1600 if (bp[2] == '.' && vim_isxdigit(bp[3]))
1601 ++bp;
1602 }
1603 if (blob != NULL)
1604 rettv_blob_set(rettv, blob);
1605 *arg = bp;
1606 }
1607 else
1608 {
1609 varnumber_T n;
1610
1611 // decimal, hex or octal number
1612 vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4
1613 ? STR2NR_NO_OCT + STR2NR_QUOTE
1614 : STR2NR_ALL, &n, NULL, 0, TRUE);
1615 if (len == 0)
1616 {
Bram Moolenaar108010a2021-06-27 22:03:33 +02001617 semsg(_(e_invalid_expression_str), *arg);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001618 return FAIL;
1619 }
1620 *arg += len;
1621 if (evaluate)
1622 {
1623 rettv->v_type = VAR_NUMBER;
1624 rettv->vval.v_number = n;
1625 }
1626 }
1627 return OK;
1628}
1629
1630/*
1631 * Allocate a variable for a string constant.
1632 * Return OK or FAIL.
1633 */
1634 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001635eval_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001636{
1637 char_u *p;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001638 char_u *end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001639 int extra = 0;
1640 int len;
1641
1642 // Find the end of the string, skipping backslashed characters.
1643 for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
1644 {
1645 if (*p == '\\' && p[1] != NUL)
1646 {
1647 ++p;
1648 // A "\<x>" form occupies at least 4 characters, and produces up
1649 // to 21 characters (3 * 6 for the char and 3 for a modifier):
1650 // reserve space for 18 extra.
1651 // Each byte in the char could be encoded as K_SPECIAL K_EXTRA x.
1652 if (*p == '<')
1653 extra += 18;
1654 }
1655 }
1656
1657 if (*p != '"')
1658 {
1659 semsg(_("E114: Missing quote: %s"), *arg);
1660 return FAIL;
1661 }
1662
1663 // If only parsing, set *arg and return here
1664 if (!evaluate)
1665 {
1666 *arg = p + 1;
1667 return OK;
1668 }
1669
1670 // Copy the string into allocated memory, handling backslashed
1671 // characters.
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001672 rettv->v_type = VAR_STRING;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001673 len = (int)(p - *arg + extra);
1674 rettv->vval.v_string = alloc(len);
1675 if (rettv->vval.v_string == NULL)
1676 return FAIL;
1677 end = rettv->vval.v_string;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001678
1679 for (p = *arg + 1; *p != NUL && *p != '"'; )
1680 {
1681 if (*p == '\\')
1682 {
1683 switch (*++p)
1684 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001685 case 'b': *end++ = BS; ++p; break;
1686 case 'e': *end++ = ESC; ++p; break;
1687 case 'f': *end++ = FF; ++p; break;
1688 case 'n': *end++ = NL; ++p; break;
1689 case 'r': *end++ = CAR; ++p; break;
1690 case 't': *end++ = TAB; ++p; break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001691
1692 case 'X': // hex: "\x1", "\x12"
1693 case 'x':
1694 case 'u': // Unicode: "\u0023"
1695 case 'U':
1696 if (vim_isxdigit(p[1]))
1697 {
1698 int n, nr;
1699 int c = toupper(*p);
1700
1701 if (c == 'X')
1702 n = 2;
1703 else if (*p == 'u')
1704 n = 4;
1705 else
1706 n = 8;
1707 nr = 0;
1708 while (--n >= 0 && vim_isxdigit(p[1]))
1709 {
1710 ++p;
1711 nr = (nr << 4) + hex2nr(*p);
1712 }
1713 ++p;
1714 // For "\u" store the number according to
1715 // 'encoding'.
1716 if (c != 'X')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001717 end += (*mb_char2bytes)(nr, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001718 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001719 *end++ = nr;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001720 }
1721 break;
1722
1723 // octal: "\1", "\12", "\123"
1724 case '0':
1725 case '1':
1726 case '2':
1727 case '3':
1728 case '4':
1729 case '5':
1730 case '6':
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001731 case '7': *end = *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001732 if (*p >= '0' && *p <= '7')
1733 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001734 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001735 if (*p >= '0' && *p <= '7')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001736 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001737 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001738 ++end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001739 break;
1740
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001741 // Special key, e.g.: "\<C-W>"
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001742 case '<':
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001743 {
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001744 int flags = FSK_KEYCODE | FSK_IN_STRING;
1745
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001746 if (p[1] != '*')
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001747 flags |= FSK_SIMPLIFY;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001748 extra = trans_special(&p, end, flags, NULL);
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001749 if (extra != 0)
1750 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001751 end += extra;
1752 if (end >= rettv->vval.v_string + len)
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001753 iemsg("eval_string() used more space than allocated");
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001754 break;
1755 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001756 }
1757 // FALLTHROUGH
1758
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001759 default: MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001760 break;
1761 }
1762 }
1763 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001764 MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001765 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001766 *end = NUL;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001767 if (*p != NUL) // just in case
1768 ++p;
1769 *arg = p;
1770
1771 return OK;
1772}
1773
1774/*
1775 * Allocate a variable for a 'str''ing' constant.
1776 * Return OK or FAIL.
1777 */
1778 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001779eval_lit_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001780{
1781 char_u *p;
1782 char_u *str;
1783 int reduce = 0;
1784
1785 // Find the end of the string, skipping ''.
1786 for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
1787 {
1788 if (*p == '\'')
1789 {
1790 if (p[1] != '\'')
1791 break;
1792 ++reduce;
1793 ++p;
1794 }
1795 }
1796
1797 if (*p != '\'')
1798 {
1799 semsg(_("E115: Missing quote: %s"), *arg);
1800 return FAIL;
1801 }
1802
1803 // If only parsing return after setting "*arg"
1804 if (!evaluate)
1805 {
1806 *arg = p + 1;
1807 return OK;
1808 }
1809
1810 // Copy the string into allocated memory, handling '' to ' reduction.
1811 str = alloc((p - *arg) - reduce);
1812 if (str == NULL)
1813 return FAIL;
1814 rettv->v_type = VAR_STRING;
1815 rettv->vval.v_string = str;
1816
1817 for (p = *arg + 1; *p != NUL; )
1818 {
1819 if (*p == '\'')
1820 {
1821 if (p[1] != '\'')
1822 break;
1823 ++p;
1824 }
1825 MB_COPY_CHAR(p, str);
1826 }
1827 *str = NUL;
1828 *arg = p + 1;
1829
1830 return OK;
1831}
1832
1833/*
1834 * Return a string with the string representation of a variable.
1835 * If the memory is allocated "tofree" is set to it, otherwise NULL.
1836 * "numbuf" is used for a number.
1837 * Puts quotes around strings, so that they can be parsed back by eval().
1838 * May return NULL.
1839 */
1840 char_u *
1841tv2string(
1842 typval_T *tv,
1843 char_u **tofree,
1844 char_u *numbuf,
1845 int copyID)
1846{
1847 return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
1848}
1849
1850/*
1851 * Get the value of an environment variable.
1852 * "arg" is pointing to the '$'. It is advanced to after the name.
1853 * If the environment variable was not set, silently assume it is empty.
1854 * Return FAIL if the name is invalid.
1855 */
1856 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001857eval_env_var(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001858{
1859 char_u *string = NULL;
1860 int len;
1861 int cc;
1862 char_u *name;
1863 int mustfree = FALSE;
1864
1865 ++*arg;
1866 name = *arg;
1867 len = get_env_len(arg);
1868 if (evaluate)
1869 {
1870 if (len == 0)
1871 return FAIL; // invalid empty name
1872
1873 cc = name[len];
1874 name[len] = NUL;
1875 // first try vim_getenv(), fast for normal environment vars
1876 string = vim_getenv(name, &mustfree);
1877 if (string != NULL && *string != NUL)
1878 {
1879 if (!mustfree)
1880 string = vim_strsave(string);
1881 }
1882 else
1883 {
1884 if (mustfree)
1885 vim_free(string);
1886
1887 // next try expanding things like $VIM and ${HOME}
1888 string = expand_env_save(name - 1);
1889 if (string != NULL && *string == '$')
1890 VIM_CLEAR(string);
1891 }
1892 name[len] = cc;
1893
1894 rettv->v_type = VAR_STRING;
1895 rettv->vval.v_string = string;
1896 }
1897
1898 return OK;
1899}
1900
1901/*
1902 * Get the lnum from the first argument.
1903 * Also accepts ".", "$", etc., but that only works for the current buffer.
1904 * Returns -1 on error.
1905 */
1906 linenr_T
1907tv_get_lnum(typval_T *argvars)
1908{
Bram Moolenaar9a963372020-12-21 21:58:46 +01001909 linenr_T lnum = -1;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001910
Bram Moolenaar56acb092020-08-16 14:48:19 +02001911 if (argvars[0].v_type != VAR_STRING || !in_vim9script())
1912 lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL);
Bram Moolenaarf6bdd822021-03-28 16:26:41 +02001913 if (lnum <= 0 && argvars[0].v_type != VAR_NUMBER)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001914 {
1915 int fnum;
Bram Moolenaar6f02b002021-01-10 20:22:54 +01001916 pos_T *fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001917
Bram Moolenaarf6bdd822021-03-28 16:26:41 +02001918 // no valid number, try using arg like line()
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001919 if (fp != NULL)
1920 lnum = fp->lnum;
1921 }
1922 return lnum;
1923}
1924
1925/*
1926 * Get the lnum from the first argument.
1927 * Also accepts "$", then "buf" is used.
1928 * Returns 0 on error.
1929 */
1930 linenr_T
1931tv_get_lnum_buf(typval_T *argvars, buf_T *buf)
1932{
1933 if (argvars[0].v_type == VAR_STRING
1934 && argvars[0].vval.v_string != NULL
1935 && argvars[0].vval.v_string[0] == '$'
1936 && buf != NULL)
1937 return buf->b_ml.ml_line_count;
1938 return (linenr_T)tv_get_number_chk(&argvars[0], NULL);
1939}
1940
1941/*
1942 * Get buffer by number or pattern.
1943 */
1944 buf_T *
1945tv_get_buf(typval_T *tv, int curtab_only)
1946{
1947 char_u *name = tv->vval.v_string;
1948 buf_T *buf;
1949
1950 if (tv->v_type == VAR_NUMBER)
1951 return buflist_findnr((int)tv->vval.v_number);
1952 if (tv->v_type != VAR_STRING)
1953 return NULL;
1954 if (name == NULL || *name == NUL)
1955 return curbuf;
1956 if (name[0] == '$' && name[1] == NUL)
1957 return lastbuf;
1958
1959 buf = buflist_find_by_name(name, curtab_only);
1960
1961 // If not found, try expanding the name, like done for bufexists().
1962 if (buf == NULL)
1963 buf = find_buffer(tv);
1964
1965 return buf;
1966}
1967
Bram Moolenaar3767e3a2020-09-01 23:06:01 +02001968/*
1969 * Like tv_get_buf() but give an error message is the type is wrong.
1970 */
1971 buf_T *
1972tv_get_buf_from_arg(typval_T *tv)
1973{
1974 buf_T *buf;
1975
1976 ++emsg_off;
1977 buf = tv_get_buf(tv, FALSE);
1978 --emsg_off;
1979 if (buf == NULL
1980 && tv->v_type != VAR_NUMBER
1981 && tv->v_type != VAR_STRING)
1982 // issue errmsg for type error
1983 (void)tv_get_number(tv);
1984 return buf;
1985}
1986
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001987#endif // FEAT_EVAL