blob: 053f30077e1d0745151b2f1af997af04b8017fab [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:
94 break;
95 }
96 vim_free(varp);
97 }
98}
99
100/*
101 * Free the memory for a variable value and set the value to NULL or 0.
102 */
103 void
104clear_tv(typval_T *varp)
105{
106 if (varp != NULL)
107 {
108 switch (varp->v_type)
109 {
110 case VAR_FUNC:
111 func_unref(varp->vval.v_string);
112 // FALLTHROUGH
113 case VAR_STRING:
114 VIM_CLEAR(varp->vval.v_string);
115 break;
116 case VAR_PARTIAL:
117 partial_unref(varp->vval.v_partial);
118 varp->vval.v_partial = NULL;
119 break;
120 case VAR_BLOB:
121 blob_unref(varp->vval.v_blob);
122 varp->vval.v_blob = NULL;
123 break;
124 case VAR_LIST:
125 list_unref(varp->vval.v_list);
126 varp->vval.v_list = NULL;
127 break;
128 case VAR_DICT:
129 dict_unref(varp->vval.v_dict);
130 varp->vval.v_dict = NULL;
131 break;
132 case VAR_NUMBER:
133 case VAR_BOOL:
134 case VAR_SPECIAL:
135 varp->vval.v_number = 0;
136 break;
137 case VAR_FLOAT:
138#ifdef FEAT_FLOAT
139 varp->vval.v_float = 0.0;
140 break;
141#endif
142 case VAR_JOB:
143#ifdef FEAT_JOB_CHANNEL
144 job_unref(varp->vval.v_job);
145 varp->vval.v_job = NULL;
146#endif
147 break;
148 case VAR_CHANNEL:
149#ifdef FEAT_JOB_CHANNEL
150 channel_unref(varp->vval.v_channel);
151 varp->vval.v_channel = NULL;
152#endif
153 case VAR_UNKNOWN:
154 case VAR_ANY:
155 case VAR_VOID:
156 break;
157 }
158 varp->v_lock = 0;
159 }
160}
161
162/*
163 * Set the value of a variable to NULL without freeing items.
164 */
165 void
166init_tv(typval_T *varp)
167{
168 if (varp != NULL)
169 CLEAR_POINTER(varp);
170}
171
Bram Moolenaar36967b32020-08-17 21:41:02 +0200172 static varnumber_T
173tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200174{
175 varnumber_T n = 0L;
176
177 switch (varp->v_type)
178 {
179 case VAR_NUMBER:
180 return varp->vval.v_number;
181 case VAR_FLOAT:
182#ifdef FEAT_FLOAT
183 emsg(_("E805: Using a Float as a Number"));
184 break;
185#endif
186 case VAR_FUNC:
187 case VAR_PARTIAL:
188 emsg(_("E703: Using a Funcref as a Number"));
189 break;
190 case VAR_STRING:
Bram Moolenaar56acb092020-08-16 14:48:19 +0200191 if (in_vim9script())
192 {
193 emsg(_(e_using_string_as_number));
194 break;
195 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200196 if (varp->vval.v_string != NULL)
197 vim_str2nr(varp->vval.v_string, NULL, NULL,
198 STR2NR_ALL, &n, NULL, 0, FALSE);
199 return n;
200 case VAR_LIST:
201 emsg(_("E745: Using a List as a Number"));
202 break;
203 case VAR_DICT:
204 emsg(_("E728: Using a Dictionary as a Number"));
205 break;
206 case VAR_BOOL:
207 case VAR_SPECIAL:
Bram Moolenaar36967b32020-08-17 21:41:02 +0200208 if (!want_bool && in_vim9script())
Bram Moolenaar56acb092020-08-16 14:48:19 +0200209 {
210 emsg(_("E611: Using a Special as a Number"));
211 break;
212 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200213 return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
214 case VAR_JOB:
215#ifdef FEAT_JOB_CHANNEL
216 emsg(_("E910: Using a Job as a Number"));
217 break;
218#endif
219 case VAR_CHANNEL:
220#ifdef FEAT_JOB_CHANNEL
221 emsg(_("E913: Using a Channel as a Number"));
222 break;
223#endif
224 case VAR_BLOB:
225 emsg(_("E974: Using a Blob as a Number"));
226 break;
227 case VAR_UNKNOWN:
228 case VAR_ANY:
229 case VAR_VOID:
230 internal_error_no_abort("tv_get_number(UNKNOWN)");
231 break;
232 }
233 if (denote == NULL) // useful for values that must be unsigned
234 n = -1;
235 else
236 *denote = TRUE;
237 return n;
238}
239
Bram Moolenaar36967b32020-08-17 21:41:02 +0200240/*
241 * Get the number value of a variable.
242 * If it is a String variable, uses vim_str2nr().
243 * For incompatible types, return 0.
244 * tv_get_number_chk() is similar to tv_get_number(), but informs the
245 * caller of incompatible types: it sets *denote to TRUE if "denote"
246 * is not NULL or returns -1 otherwise.
247 */
248 varnumber_T
249tv_get_number(typval_T *varp)
250{
251 int error = FALSE;
252
253 return tv_get_number_chk(varp, &error); // return 0L on error
254}
255
256 varnumber_T
257tv_get_number_chk(typval_T *varp, int *denote)
258{
259 return tv_get_bool_or_number_chk(varp, denote, FALSE);
260}
261
262/*
263 * Get the boolean value of "varp". This is like tv_get_number_chk(),
264 * but in Vim9 script accepts Number and Bool.
265 */
266 varnumber_T
267tv_get_bool(typval_T *varp)
268{
269 return tv_get_bool_or_number_chk(varp, NULL, TRUE);
270
271}
272
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200273#ifdef FEAT_FLOAT
274 float_T
275tv_get_float(typval_T *varp)
276{
277 switch (varp->v_type)
278 {
279 case VAR_NUMBER:
280 return (float_T)(varp->vval.v_number);
281 case VAR_FLOAT:
282 return varp->vval.v_float;
283 case VAR_FUNC:
284 case VAR_PARTIAL:
285 emsg(_("E891: Using a Funcref as a Float"));
286 break;
287 case VAR_STRING:
288 emsg(_("E892: Using a String as a Float"));
289 break;
290 case VAR_LIST:
291 emsg(_("E893: Using a List as a Float"));
292 break;
293 case VAR_DICT:
294 emsg(_("E894: Using a Dictionary as a Float"));
295 break;
296 case VAR_BOOL:
297 emsg(_("E362: Using a boolean value as a Float"));
298 break;
299 case VAR_SPECIAL:
300 emsg(_("E907: Using a special value as a Float"));
301 break;
302 case VAR_JOB:
303# ifdef FEAT_JOB_CHANNEL
304 emsg(_("E911: Using a Job as a Float"));
305 break;
306# endif
307 case VAR_CHANNEL:
308# ifdef FEAT_JOB_CHANNEL
309 emsg(_("E914: Using a Channel as a Float"));
310 break;
311# endif
312 case VAR_BLOB:
313 emsg(_("E975: Using a Blob as a Float"));
314 break;
315 case VAR_UNKNOWN:
316 case VAR_ANY:
317 case VAR_VOID:
318 internal_error_no_abort("tv_get_float(UNKNOWN)");
319 break;
320 }
321 return 0;
322}
323#endif
324
325/*
326 * Get the string value of a variable.
327 * If it is a Number variable, the number is converted into a string.
328 * tv_get_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
329 * tv_get_string_buf() uses a given buffer.
330 * If the String variable has never been set, return an empty string.
331 * Never returns NULL;
332 * tv_get_string_chk() and tv_get_string_buf_chk() are similar, but return
333 * NULL on error.
334 */
335 char_u *
336tv_get_string(typval_T *varp)
337{
338 static char_u mybuf[NUMBUFLEN];
339
340 return tv_get_string_buf(varp, mybuf);
341}
342
343 char_u *
344tv_get_string_buf(typval_T *varp, char_u *buf)
345{
346 char_u *res = tv_get_string_buf_chk(varp, buf);
347
348 return res != NULL ? res : (char_u *)"";
349}
350
351/*
352 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
353 */
354 char_u *
355tv_get_string_chk(typval_T *varp)
356{
357 static char_u mybuf[NUMBUFLEN];
358
359 return tv_get_string_buf_chk(varp, mybuf);
360}
361
362 char_u *
363tv_get_string_buf_chk(typval_T *varp, char_u *buf)
364{
365 switch (varp->v_type)
366 {
367 case VAR_NUMBER:
368 vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
369 (varnumber_T)varp->vval.v_number);
370 return buf;
371 case VAR_FUNC:
372 case VAR_PARTIAL:
373 emsg(_("E729: using Funcref as a String"));
374 break;
375 case VAR_LIST:
376 emsg(_("E730: using List as a String"));
377 break;
378 case VAR_DICT:
379 emsg(_("E731: using Dictionary as a String"));
380 break;
381 case VAR_FLOAT:
382#ifdef FEAT_FLOAT
383 emsg(_(e_float_as_string));
384 break;
385#endif
386 case VAR_STRING:
387 if (varp->vval.v_string != NULL)
388 return varp->vval.v_string;
389 return (char_u *)"";
390 case VAR_BOOL:
391 case VAR_SPECIAL:
392 STRCPY(buf, get_var_special_name(varp->vval.v_number));
393 return buf;
394 case VAR_BLOB:
395 emsg(_("E976: using Blob as a String"));
396 break;
397 case VAR_JOB:
398#ifdef FEAT_JOB_CHANNEL
399 {
400 job_T *job = varp->vval.v_job;
401 char *status;
402
403 if (job == NULL)
404 return (char_u *)"no process";
405 status = job->jv_status == JOB_FAILED ? "fail"
406 : job->jv_status >= JOB_ENDED ? "dead"
407 : "run";
408# ifdef UNIX
409 vim_snprintf((char *)buf, NUMBUFLEN,
410 "process %ld %s", (long)job->jv_pid, status);
411# elif defined(MSWIN)
412 vim_snprintf((char *)buf, NUMBUFLEN,
413 "process %ld %s",
414 (long)job->jv_proc_info.dwProcessId,
415 status);
416# else
417 // fall-back
418 vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
419# endif
420 return buf;
421 }
422#endif
423 break;
424 case VAR_CHANNEL:
425#ifdef FEAT_JOB_CHANNEL
426 {
427 channel_T *channel = varp->vval.v_channel;
428 char *status = channel_status(channel, -1);
429
430 if (channel == NULL)
431 vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
432 else
433 vim_snprintf((char *)buf, NUMBUFLEN,
434 "channel %d %s", channel->ch_id, status);
435 return buf;
436 }
437#endif
438 break;
439 case VAR_UNKNOWN:
440 case VAR_ANY:
441 case VAR_VOID:
442 emsg(_(e_inval_string));
443 break;
444 }
445 return NULL;
446}
447
448/*
449 * Turn a typeval into a string. Similar to tv_get_string_buf() but uses
450 * string() on Dict, List, etc.
451 */
452 char_u *
453tv_stringify(typval_T *varp, char_u *buf)
454{
455 if (varp->v_type == VAR_LIST
456 || varp->v_type == VAR_DICT
457 || varp->v_type == VAR_BLOB
458 || varp->v_type == VAR_FUNC
459 || varp->v_type == VAR_PARTIAL
460 || varp->v_type == VAR_FLOAT)
461 {
462 typval_T tmp;
463
464 f_string(varp, &tmp);
465 tv_get_string_buf(&tmp, buf);
466 clear_tv(varp);
467 *varp = tmp;
468 return tmp.vval.v_string;
469 }
470 return tv_get_string_buf(varp, buf);
471}
472
473/*
474 * Return TRUE if typeval "tv" and its value are set to be locked (immutable).
475 * Also give an error message, using "name" or _("name") when use_gettext is
476 * TRUE.
477 */
478 int
479tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
480{
481 int lock = 0;
482
483 switch (tv->v_type)
484 {
485 case VAR_BLOB:
486 if (tv->vval.v_blob != NULL)
487 lock = tv->vval.v_blob->bv_lock;
488 break;
489 case VAR_LIST:
490 if (tv->vval.v_list != NULL)
491 lock = tv->vval.v_list->lv_lock;
492 break;
493 case VAR_DICT:
494 if (tv->vval.v_dict != NULL)
495 lock = tv->vval.v_dict->dv_lock;
496 break;
497 default:
498 break;
499 }
500 return var_check_lock(tv->v_lock, name, use_gettext)
501 || (lock != 0 && var_check_lock(lock, name, use_gettext));
502}
503
504/*
505 * Copy the values from typval_T "from" to typval_T "to".
506 * When needed allocates string or increases reference count.
507 * Does not make a copy of a list, blob or dict but copies the reference!
508 * It is OK for "from" and "to" to point to the same item. This is used to
509 * make a copy later.
510 */
511 void
512copy_tv(typval_T *from, typval_T *to)
513{
514 to->v_type = from->v_type;
515 to->v_lock = 0;
516 switch (from->v_type)
517 {
518 case VAR_NUMBER:
519 case VAR_BOOL:
520 case VAR_SPECIAL:
521 to->vval.v_number = from->vval.v_number;
522 break;
523 case VAR_FLOAT:
524#ifdef FEAT_FLOAT
525 to->vval.v_float = from->vval.v_float;
526 break;
527#endif
528 case VAR_JOB:
529#ifdef FEAT_JOB_CHANNEL
530 to->vval.v_job = from->vval.v_job;
531 if (to->vval.v_job != NULL)
532 ++to->vval.v_job->jv_refcount;
533 break;
534#endif
535 case VAR_CHANNEL:
536#ifdef FEAT_JOB_CHANNEL
537 to->vval.v_channel = from->vval.v_channel;
538 if (to->vval.v_channel != NULL)
539 ++to->vval.v_channel->ch_refcount;
540 break;
541#endif
542 case VAR_STRING:
543 case VAR_FUNC:
544 if (from->vval.v_string == NULL)
545 to->vval.v_string = NULL;
546 else
547 {
548 to->vval.v_string = vim_strsave(from->vval.v_string);
549 if (from->v_type == VAR_FUNC)
550 func_ref(to->vval.v_string);
551 }
552 break;
553 case VAR_PARTIAL:
554 if (from->vval.v_partial == NULL)
555 to->vval.v_partial = NULL;
556 else
557 {
558 to->vval.v_partial = from->vval.v_partial;
559 ++to->vval.v_partial->pt_refcount;
560 }
561 break;
562 case VAR_BLOB:
563 if (from->vval.v_blob == NULL)
564 to->vval.v_blob = NULL;
565 else
566 {
567 to->vval.v_blob = from->vval.v_blob;
568 ++to->vval.v_blob->bv_refcount;
569 }
570 break;
571 case VAR_LIST:
572 if (from->vval.v_list == NULL)
573 to->vval.v_list = NULL;
574 else
575 {
576 to->vval.v_list = from->vval.v_list;
577 ++to->vval.v_list->lv_refcount;
578 }
579 break;
580 case VAR_DICT:
581 if (from->vval.v_dict == NULL)
582 to->vval.v_dict = NULL;
583 else
584 {
585 to->vval.v_dict = from->vval.v_dict;
586 ++to->vval.v_dict->dv_refcount;
587 }
588 break;
589 case VAR_UNKNOWN:
590 case VAR_ANY:
591 case VAR_VOID:
592 internal_error_no_abort("copy_tv(UNKNOWN)");
593 break;
594 }
595}
596
597/*
598 * Compare "typ1" and "typ2". Put the result in "typ1".
599 */
600 int
601typval_compare(
602 typval_T *typ1, // first operand
603 typval_T *typ2, // second operand
604 exptype_T type, // operator
605 int ic) // ignore case
606{
607 int i;
608 varnumber_T n1, n2;
609 char_u *s1, *s2;
610 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
611 int type_is = type == EXPR_IS || type == EXPR_ISNOT;
612
613 if (type_is && typ1->v_type != typ2->v_type)
614 {
615 // For "is" a different type always means FALSE, for "notis"
616 // it means TRUE.
617 n1 = (type == EXPR_ISNOT);
618 }
619 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
620 {
621 if (type_is)
622 {
623 n1 = (typ1->v_type == typ2->v_type
624 && typ1->vval.v_blob == typ2->vval.v_blob);
625 if (type == EXPR_ISNOT)
626 n1 = !n1;
627 }
628 else if (typ1->v_type != typ2->v_type
629 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
630 {
631 if (typ1->v_type != typ2->v_type)
632 emsg(_("E977: Can only compare Blob with Blob"));
633 else
634 emsg(_(e_invalblob));
635 clear_tv(typ1);
636 return FAIL;
637 }
638 else
639 {
640 // Compare two Blobs for being equal or unequal.
641 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
642 if (type == EXPR_NEQUAL)
643 n1 = !n1;
644 }
645 }
646 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
647 {
648 if (type_is)
649 {
650 n1 = (typ1->v_type == typ2->v_type
651 && typ1->vval.v_list == typ2->vval.v_list);
652 if (type == EXPR_ISNOT)
653 n1 = !n1;
654 }
655 else if (typ1->v_type != typ2->v_type
656 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
657 {
658 if (typ1->v_type != typ2->v_type)
659 emsg(_("E691: Can only compare List with List"));
660 else
661 emsg(_("E692: Invalid operation for List"));
662 clear_tv(typ1);
663 return FAIL;
664 }
665 else
666 {
667 // Compare two Lists for being equal or unequal.
668 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
669 ic, FALSE);
670 if (type == EXPR_NEQUAL)
671 n1 = !n1;
672 }
673 }
674
675 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
676 {
677 if (type_is)
678 {
679 n1 = (typ1->v_type == typ2->v_type
680 && typ1->vval.v_dict == typ2->vval.v_dict);
681 if (type == EXPR_ISNOT)
682 n1 = !n1;
683 }
684 else if (typ1->v_type != typ2->v_type
685 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
686 {
687 if (typ1->v_type != typ2->v_type)
688 emsg(_("E735: Can only compare Dictionary with Dictionary"));
689 else
690 emsg(_("E736: Invalid operation for Dictionary"));
691 clear_tv(typ1);
692 return FAIL;
693 }
694 else
695 {
696 // Compare two Dictionaries for being equal or unequal.
697 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
698 ic, FALSE);
699 if (type == EXPR_NEQUAL)
700 n1 = !n1;
701 }
702 }
703
704 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
705 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
706 {
707 if (type != EXPR_EQUAL && type != EXPR_NEQUAL
708 && type != EXPR_IS && type != EXPR_ISNOT)
709 {
710 emsg(_("E694: Invalid operation for Funcrefs"));
711 clear_tv(typ1);
712 return FAIL;
713 }
714 if ((typ1->v_type == VAR_PARTIAL
715 && typ1->vval.v_partial == NULL)
716 || (typ2->v_type == VAR_PARTIAL
717 && typ2->vval.v_partial == NULL))
718 // When both partials are NULL, then they are equal.
719 // Otherwise they are not equal.
720 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
721 else if (type_is)
722 {
723 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
724 // strings are considered the same if their value is
725 // the same
726 n1 = tv_equal(typ1, typ2, ic, FALSE);
727 else if (typ1->v_type == VAR_PARTIAL
728 && typ2->v_type == VAR_PARTIAL)
729 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
730 else
731 n1 = FALSE;
732 }
733 else
734 n1 = tv_equal(typ1, typ2, ic, FALSE);
735 if (type == EXPR_NEQUAL || type == EXPR_ISNOT)
736 n1 = !n1;
737 }
738
739#ifdef FEAT_FLOAT
740 // If one of the two variables is a float, compare as a float.
741 // When using "=~" or "!~", always compare as string.
742 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
743 && type != EXPR_MATCH && type != EXPR_NOMATCH)
744 {
745 float_T f1, f2;
746
747 f1 = tv_get_float(typ1);
748 f2 = tv_get_float(typ2);
749 n1 = FALSE;
750 switch (type)
751 {
752 case EXPR_IS:
753 case EXPR_EQUAL: n1 = (f1 == f2); break;
754 case EXPR_ISNOT:
755 case EXPR_NEQUAL: n1 = (f1 != f2); break;
756 case EXPR_GREATER: n1 = (f1 > f2); break;
757 case EXPR_GEQUAL: n1 = (f1 >= f2); break;
758 case EXPR_SMALLER: n1 = (f1 < f2); break;
759 case EXPR_SEQUAL: n1 = (f1 <= f2); break;
760 case EXPR_UNKNOWN:
761 case EXPR_MATCH:
762 default: break; // avoid gcc warning
763 }
764 }
765#endif
766
767 // If one of the two variables is a number, compare as a number.
768 // When using "=~" or "!~", always compare as string.
769 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
770 && type != EXPR_MATCH && type != EXPR_NOMATCH)
771 {
772 n1 = tv_get_number(typ1);
773 n2 = tv_get_number(typ2);
774 switch (type)
775 {
776 case EXPR_IS:
777 case EXPR_EQUAL: n1 = (n1 == n2); break;
778 case EXPR_ISNOT:
779 case EXPR_NEQUAL: n1 = (n1 != n2); break;
780 case EXPR_GREATER: n1 = (n1 > n2); break;
781 case EXPR_GEQUAL: n1 = (n1 >= n2); break;
782 case EXPR_SMALLER: n1 = (n1 < n2); break;
783 case EXPR_SEQUAL: n1 = (n1 <= n2); break;
784 case EXPR_UNKNOWN:
785 case EXPR_MATCH:
786 default: break; // avoid gcc warning
787 }
788 }
789 else
790 {
791 s1 = tv_get_string_buf(typ1, buf1);
792 s2 = tv_get_string_buf(typ2, buf2);
793 if (type != EXPR_MATCH && type != EXPR_NOMATCH)
794 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
795 else
796 i = 0;
797 n1 = FALSE;
798 switch (type)
799 {
800 case EXPR_IS:
801 case EXPR_EQUAL: n1 = (i == 0); break;
802 case EXPR_ISNOT:
803 case EXPR_NEQUAL: n1 = (i != 0); break;
804 case EXPR_GREATER: n1 = (i > 0); break;
805 case EXPR_GEQUAL: n1 = (i >= 0); break;
806 case EXPR_SMALLER: n1 = (i < 0); break;
807 case EXPR_SEQUAL: n1 = (i <= 0); break;
808
809 case EXPR_MATCH:
810 case EXPR_NOMATCH:
811 n1 = pattern_match(s2, s1, ic);
812 if (type == EXPR_NOMATCH)
813 n1 = !n1;
814 break;
815
816 default: break; // avoid gcc warning
817 }
818 }
819 clear_tv(typ1);
Bram Moolenaarc71f36a2020-07-21 21:31:00 +0200820 if (in_vim9script())
821 {
822 typ1->v_type = VAR_BOOL;
823 typ1->vval.v_number = n1 ? VVAL_TRUE : VVAL_FALSE;
824 }
825 else
826 {
827 typ1->v_type = VAR_NUMBER;
828 typ1->vval.v_number = n1;
829 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200830
831 return OK;
832}
833
834 char_u *
835typval_tostring(typval_T *arg)
836{
837 char_u *tofree;
838 char_u numbuf[NUMBUFLEN];
839 char_u *ret = NULL;
840
841 if (arg == NULL)
842 return vim_strsave((char_u *)"(does not exist)");
843 ret = tv2string(arg, &tofree, numbuf, 0);
844 // Make a copy if we have a value but it's not in allocated memory.
845 if (ret != NULL && tofree == NULL)
846 ret = vim_strsave(ret);
847 return ret;
848}
849
850/*
851 * Return TRUE if typeval "tv" is locked: Either that value is locked itself
852 * or it refers to a List or Dictionary that is locked.
853 */
854 int
855tv_islocked(typval_T *tv)
856{
857 return (tv->v_lock & VAR_LOCKED)
858 || (tv->v_type == VAR_LIST
859 && tv->vval.v_list != NULL
860 && (tv->vval.v_list->lv_lock & VAR_LOCKED))
861 || (tv->v_type == VAR_DICT
862 && tv->vval.v_dict != NULL
863 && (tv->vval.v_dict->dv_lock & VAR_LOCKED));
864}
865
866 static int
867func_equal(
868 typval_T *tv1,
869 typval_T *tv2,
870 int ic) // ignore case
871{
872 char_u *s1, *s2;
873 dict_T *d1, *d2;
874 int a1, a2;
875 int i;
876
877 // empty and NULL function name considered the same
878 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
879 : partial_name(tv1->vval.v_partial);
880 if (s1 != NULL && *s1 == NUL)
881 s1 = NULL;
882 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
883 : partial_name(tv2->vval.v_partial);
884 if (s2 != NULL && *s2 == NUL)
885 s2 = NULL;
886 if (s1 == NULL || s2 == NULL)
887 {
888 if (s1 != s2)
889 return FALSE;
890 }
891 else if (STRCMP(s1, s2) != 0)
892 return FALSE;
893
894 // empty dict and NULL dict is different
895 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
896 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
897 if (d1 == NULL || d2 == NULL)
898 {
899 if (d1 != d2)
900 return FALSE;
901 }
902 else if (!dict_equal(d1, d2, ic, TRUE))
903 return FALSE;
904
905 // empty list and no list considered the same
906 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
907 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
908 if (a1 != a2)
909 return FALSE;
910 for (i = 0; i < a1; ++i)
911 if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
912 tv2->vval.v_partial->pt_argv + i, ic, TRUE))
913 return FALSE;
914
915 return TRUE;
916}
917
918/*
919 * Return TRUE if "tv1" and "tv2" have the same value.
920 * Compares the items just like "==" would compare them, but strings and
921 * numbers are different. Floats and numbers are also different.
922 */
923 int
924tv_equal(
925 typval_T *tv1,
926 typval_T *tv2,
927 int ic, // ignore case
928 int recursive) // TRUE when used recursively
929{
930 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
931 char_u *s1, *s2;
932 static int recursive_cnt = 0; // catch recursive loops
933 int r;
934 static int tv_equal_recurse_limit;
935
936 // Catch lists and dicts that have an endless loop by limiting
937 // recursiveness to a limit. We guess they are equal then.
938 // A fixed limit has the problem of still taking an awful long time.
939 // Reduce the limit every time running into it. That should work fine for
940 // deeply linked structures that are not recursively linked and catch
941 // recursiveness quickly.
942 if (!recursive)
943 tv_equal_recurse_limit = 1000;
944 if (recursive_cnt >= tv_equal_recurse_limit)
945 {
946 --tv_equal_recurse_limit;
947 return TRUE;
948 }
949
950 // For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and
951 // arguments.
952 if ((tv1->v_type == VAR_FUNC
953 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
954 && (tv2->v_type == VAR_FUNC
955 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
956 {
957 ++recursive_cnt;
958 r = func_equal(tv1, tv2, ic);
959 --recursive_cnt;
960 return r;
961 }
962
963 if (tv1->v_type != tv2->v_type)
964 return FALSE;
965
966 switch (tv1->v_type)
967 {
968 case VAR_LIST:
969 ++recursive_cnt;
970 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
971 --recursive_cnt;
972 return r;
973
974 case VAR_DICT:
975 ++recursive_cnt;
976 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
977 --recursive_cnt;
978 return r;
979
980 case VAR_BLOB:
981 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
982
983 case VAR_NUMBER:
984 case VAR_BOOL:
985 case VAR_SPECIAL:
986 return tv1->vval.v_number == tv2->vval.v_number;
987
988 case VAR_STRING:
989 s1 = tv_get_string_buf(tv1, buf1);
990 s2 = tv_get_string_buf(tv2, buf2);
991 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
992
993 case VAR_FLOAT:
994#ifdef FEAT_FLOAT
995 return tv1->vval.v_float == tv2->vval.v_float;
996#endif
997 case VAR_JOB:
998#ifdef FEAT_JOB_CHANNEL
999 return tv1->vval.v_job == tv2->vval.v_job;
1000#endif
1001 case VAR_CHANNEL:
1002#ifdef FEAT_JOB_CHANNEL
1003 return tv1->vval.v_channel == tv2->vval.v_channel;
1004#endif
1005
1006 case VAR_PARTIAL:
1007 return tv1->vval.v_partial == tv2->vval.v_partial;
1008
1009 case VAR_FUNC:
1010 return tv1->vval.v_string == tv2->vval.v_string;
1011
1012 case VAR_UNKNOWN:
1013 case VAR_ANY:
1014 case VAR_VOID:
1015 break;
1016 }
1017
1018 // VAR_UNKNOWN can be the result of a invalid expression, let's say it
1019 // does not equal anything, not even itself.
1020 return FALSE;
1021}
1022
1023/*
1024 * Get an option value.
1025 * "arg" points to the '&' or '+' before the option name.
1026 * "arg" is advanced to character after the option name.
1027 * Return OK or FAIL.
1028 */
1029 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001030eval_option(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001031 char_u **arg,
1032 typval_T *rettv, // when NULL, only check if option exists
1033 int evaluate)
1034{
1035 char_u *option_end;
1036 long numval;
1037 char_u *stringval;
1038 int opt_type;
1039 int c;
1040 int working = (**arg == '+'); // has("+option")
1041 int ret = OK;
1042 int opt_flags;
1043
1044 // Isolate the option name and find its value.
1045 option_end = find_option_end(arg, &opt_flags);
1046 if (option_end == NULL)
1047 {
1048 if (rettv != NULL)
1049 semsg(_("E112: Option name missing: %s"), *arg);
1050 return FAIL;
1051 }
1052
1053 if (!evaluate)
1054 {
1055 *arg = option_end;
1056 return OK;
1057 }
1058
1059 c = *option_end;
1060 *option_end = NUL;
1061 opt_type = get_option_value(*arg, &numval,
1062 rettv == NULL ? NULL : &stringval, opt_flags);
1063
1064 if (opt_type == -3) // invalid name
1065 {
1066 if (rettv != NULL)
1067 semsg(_(e_unknown_option), *arg);
1068 ret = FAIL;
1069 }
1070 else if (rettv != NULL)
1071 {
1072 if (opt_type == -2) // hidden string option
1073 {
1074 rettv->v_type = VAR_STRING;
1075 rettv->vval.v_string = NULL;
1076 }
1077 else if (opt_type == -1) // hidden number option
1078 {
1079 rettv->v_type = VAR_NUMBER;
1080 rettv->vval.v_number = 0;
1081 }
1082 else if (opt_type == 1) // number option
1083 {
1084 rettv->v_type = VAR_NUMBER;
1085 rettv->vval.v_number = numval;
1086 }
1087 else // string option
1088 {
1089 rettv->v_type = VAR_STRING;
1090 rettv->vval.v_string = stringval;
1091 }
1092 }
1093 else if (working && (opt_type == -2 || opt_type == -1))
1094 ret = FAIL;
1095
1096 *option_end = c; // put back for error messages
1097 *arg = option_end;
1098
1099 return ret;
1100}
1101
1102/*
1103 * Allocate a variable for a number constant. Also deals with "0z" for blob.
1104 * Return OK or FAIL.
1105 */
1106 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001107eval_number(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001108 char_u **arg,
1109 typval_T *rettv,
1110 int evaluate,
1111 int want_string UNUSED)
1112{
1113 int len;
1114#ifdef FEAT_FLOAT
1115 char_u *p;
1116 int get_float = FALSE;
1117
1118 // We accept a float when the format matches
1119 // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
1120 // strict to avoid backwards compatibility problems.
1121 // With script version 2 and later the leading digit can be
1122 // omitted.
1123 // Don't look for a float after the "." operator, so that
1124 // ":let vers = 1.2.3" doesn't fail.
1125 if (**arg == '.')
1126 p = *arg;
1127 else
1128 p = skipdigits(*arg + 1);
1129 if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
1130 {
1131 get_float = TRUE;
1132 p = skipdigits(p + 2);
1133 if (*p == 'e' || *p == 'E')
1134 {
1135 ++p;
1136 if (*p == '-' || *p == '+')
1137 ++p;
1138 if (!vim_isdigit(*p))
1139 get_float = FALSE;
1140 else
1141 p = skipdigits(p + 1);
1142 }
1143 if (ASCII_ISALPHA(*p) || *p == '.')
1144 get_float = FALSE;
1145 }
1146 if (get_float)
1147 {
1148 float_T f;
1149
1150 *arg += string2float(*arg, &f);
1151 if (evaluate)
1152 {
1153 rettv->v_type = VAR_FLOAT;
1154 rettv->vval.v_float = f;
1155 }
1156 }
1157 else
1158#endif
1159 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
1160 {
1161 char_u *bp;
1162 blob_T *blob = NULL; // init for gcc
1163
1164 // Blob constant: 0z0123456789abcdef
1165 if (evaluate)
1166 blob = blob_alloc();
1167 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
1168 {
1169 if (!vim_isxdigit(bp[1]))
1170 {
1171 if (blob != NULL)
1172 {
1173 emsg(_("E973: Blob literal should have an even number of hex characters"));
1174 ga_clear(&blob->bv_ga);
1175 VIM_CLEAR(blob);
1176 }
1177 return FAIL;
1178 }
1179 if (blob != NULL)
1180 ga_append(&blob->bv_ga,
1181 (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
1182 if (bp[2] == '.' && vim_isxdigit(bp[3]))
1183 ++bp;
1184 }
1185 if (blob != NULL)
1186 rettv_blob_set(rettv, blob);
1187 *arg = bp;
1188 }
1189 else
1190 {
1191 varnumber_T n;
1192
1193 // decimal, hex or octal number
1194 vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4
1195 ? STR2NR_NO_OCT + STR2NR_QUOTE
1196 : STR2NR_ALL, &n, NULL, 0, TRUE);
1197 if (len == 0)
1198 {
1199 semsg(_(e_invexpr2), *arg);
1200 return FAIL;
1201 }
1202 *arg += len;
1203 if (evaluate)
1204 {
1205 rettv->v_type = VAR_NUMBER;
1206 rettv->vval.v_number = n;
1207 }
1208 }
1209 return OK;
1210}
1211
1212/*
1213 * Allocate a variable for a string constant.
1214 * Return OK or FAIL.
1215 */
1216 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001217eval_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001218{
1219 char_u *p;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001220 char_u *end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001221 int extra = 0;
1222 int len;
1223
1224 // Find the end of the string, skipping backslashed characters.
1225 for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
1226 {
1227 if (*p == '\\' && p[1] != NUL)
1228 {
1229 ++p;
1230 // A "\<x>" form occupies at least 4 characters, and produces up
1231 // to 21 characters (3 * 6 for the char and 3 for a modifier):
1232 // reserve space for 18 extra.
1233 // Each byte in the char could be encoded as K_SPECIAL K_EXTRA x.
1234 if (*p == '<')
1235 extra += 18;
1236 }
1237 }
1238
1239 if (*p != '"')
1240 {
1241 semsg(_("E114: Missing quote: %s"), *arg);
1242 return FAIL;
1243 }
1244
1245 // If only parsing, set *arg and return here
1246 if (!evaluate)
1247 {
1248 *arg = p + 1;
1249 return OK;
1250 }
1251
1252 // Copy the string into allocated memory, handling backslashed
1253 // characters.
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001254 rettv->v_type = VAR_STRING;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001255 len = (int)(p - *arg + extra);
1256 rettv->vval.v_string = alloc(len);
1257 if (rettv->vval.v_string == NULL)
1258 return FAIL;
1259 end = rettv->vval.v_string;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001260
1261 for (p = *arg + 1; *p != NUL && *p != '"'; )
1262 {
1263 if (*p == '\\')
1264 {
1265 switch (*++p)
1266 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001267 case 'b': *end++ = BS; ++p; break;
1268 case 'e': *end++ = ESC; ++p; break;
1269 case 'f': *end++ = FF; ++p; break;
1270 case 'n': *end++ = NL; ++p; break;
1271 case 'r': *end++ = CAR; ++p; break;
1272 case 't': *end++ = TAB; ++p; break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001273
1274 case 'X': // hex: "\x1", "\x12"
1275 case 'x':
1276 case 'u': // Unicode: "\u0023"
1277 case 'U':
1278 if (vim_isxdigit(p[1]))
1279 {
1280 int n, nr;
1281 int c = toupper(*p);
1282
1283 if (c == 'X')
1284 n = 2;
1285 else if (*p == 'u')
1286 n = 4;
1287 else
1288 n = 8;
1289 nr = 0;
1290 while (--n >= 0 && vim_isxdigit(p[1]))
1291 {
1292 ++p;
1293 nr = (nr << 4) + hex2nr(*p);
1294 }
1295 ++p;
1296 // For "\u" store the number according to
1297 // 'encoding'.
1298 if (c != 'X')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001299 end += (*mb_char2bytes)(nr, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001300 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001301 *end++ = nr;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001302 }
1303 break;
1304
1305 // octal: "\1", "\12", "\123"
1306 case '0':
1307 case '1':
1308 case '2':
1309 case '3':
1310 case '4':
1311 case '5':
1312 case '6':
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001313 case '7': *end = *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001314 if (*p >= '0' && *p <= '7')
1315 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001316 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001317 if (*p >= '0' && *p <= '7')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001318 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001319 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001320 ++end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001321 break;
1322
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001323 // Special key, e.g.: "\<C-W>"
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001324 case '<':
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001325 {
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001326 int flags = FSK_KEYCODE | FSK_IN_STRING;
1327
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001328 if (p[1] != '*')
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001329 flags |= FSK_SIMPLIFY;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001330 extra = trans_special(&p, end, flags, NULL);
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001331 if (extra != 0)
1332 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001333 end += extra;
1334 if (end >= rettv->vval.v_string + len)
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001335 iemsg("eval_string() used more space than allocated");
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001336 break;
1337 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001338 }
1339 // FALLTHROUGH
1340
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001341 default: MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001342 break;
1343 }
1344 }
1345 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001346 MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001347 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001348 *end = NUL;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001349 if (*p != NUL) // just in case
1350 ++p;
1351 *arg = p;
1352
1353 return OK;
1354}
1355
1356/*
1357 * Allocate a variable for a 'str''ing' constant.
1358 * Return OK or FAIL.
1359 */
1360 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001361eval_lit_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001362{
1363 char_u *p;
1364 char_u *str;
1365 int reduce = 0;
1366
1367 // Find the end of the string, skipping ''.
1368 for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
1369 {
1370 if (*p == '\'')
1371 {
1372 if (p[1] != '\'')
1373 break;
1374 ++reduce;
1375 ++p;
1376 }
1377 }
1378
1379 if (*p != '\'')
1380 {
1381 semsg(_("E115: Missing quote: %s"), *arg);
1382 return FAIL;
1383 }
1384
1385 // If only parsing return after setting "*arg"
1386 if (!evaluate)
1387 {
1388 *arg = p + 1;
1389 return OK;
1390 }
1391
1392 // Copy the string into allocated memory, handling '' to ' reduction.
1393 str = alloc((p - *arg) - reduce);
1394 if (str == NULL)
1395 return FAIL;
1396 rettv->v_type = VAR_STRING;
1397 rettv->vval.v_string = str;
1398
1399 for (p = *arg + 1; *p != NUL; )
1400 {
1401 if (*p == '\'')
1402 {
1403 if (p[1] != '\'')
1404 break;
1405 ++p;
1406 }
1407 MB_COPY_CHAR(p, str);
1408 }
1409 *str = NUL;
1410 *arg = p + 1;
1411
1412 return OK;
1413}
1414
1415/*
1416 * Return a string with the string representation of a variable.
1417 * If the memory is allocated "tofree" is set to it, otherwise NULL.
1418 * "numbuf" is used for a number.
1419 * Puts quotes around strings, so that they can be parsed back by eval().
1420 * May return NULL.
1421 */
1422 char_u *
1423tv2string(
1424 typval_T *tv,
1425 char_u **tofree,
1426 char_u *numbuf,
1427 int copyID)
1428{
1429 return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
1430}
1431
1432/*
1433 * Get the value of an environment variable.
1434 * "arg" is pointing to the '$'. It is advanced to after the name.
1435 * If the environment variable was not set, silently assume it is empty.
1436 * Return FAIL if the name is invalid.
1437 */
1438 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001439eval_env_var(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001440{
1441 char_u *string = NULL;
1442 int len;
1443 int cc;
1444 char_u *name;
1445 int mustfree = FALSE;
1446
1447 ++*arg;
1448 name = *arg;
1449 len = get_env_len(arg);
1450 if (evaluate)
1451 {
1452 if (len == 0)
1453 return FAIL; // invalid empty name
1454
1455 cc = name[len];
1456 name[len] = NUL;
1457 // first try vim_getenv(), fast for normal environment vars
1458 string = vim_getenv(name, &mustfree);
1459 if (string != NULL && *string != NUL)
1460 {
1461 if (!mustfree)
1462 string = vim_strsave(string);
1463 }
1464 else
1465 {
1466 if (mustfree)
1467 vim_free(string);
1468
1469 // next try expanding things like $VIM and ${HOME}
1470 string = expand_env_save(name - 1);
1471 if (string != NULL && *string == '$')
1472 VIM_CLEAR(string);
1473 }
1474 name[len] = cc;
1475
1476 rettv->v_type = VAR_STRING;
1477 rettv->vval.v_string = string;
1478 }
1479
1480 return OK;
1481}
1482
1483/*
1484 * Get the lnum from the first argument.
1485 * Also accepts ".", "$", etc., but that only works for the current buffer.
1486 * Returns -1 on error.
1487 */
1488 linenr_T
1489tv_get_lnum(typval_T *argvars)
1490{
Bram Moolenaar56acb092020-08-16 14:48:19 +02001491 linenr_T lnum = 0;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001492
Bram Moolenaar56acb092020-08-16 14:48:19 +02001493 if (argvars[0].v_type != VAR_STRING || !in_vim9script())
1494 lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001495 if (lnum == 0) // no valid number, try using arg like line()
1496 {
1497 int fnum;
1498 pos_T *fp = var2fpos(&argvars[0], TRUE, &fnum);
1499
1500 if (fp != NULL)
1501 lnum = fp->lnum;
1502 }
1503 return lnum;
1504}
1505
1506/*
1507 * Get the lnum from the first argument.
1508 * Also accepts "$", then "buf" is used.
1509 * Returns 0 on error.
1510 */
1511 linenr_T
1512tv_get_lnum_buf(typval_T *argvars, buf_T *buf)
1513{
1514 if (argvars[0].v_type == VAR_STRING
1515 && argvars[0].vval.v_string != NULL
1516 && argvars[0].vval.v_string[0] == '$'
1517 && buf != NULL)
1518 return buf->b_ml.ml_line_count;
1519 return (linenr_T)tv_get_number_chk(&argvars[0], NULL);
1520}
1521
1522/*
1523 * Get buffer by number or pattern.
1524 */
1525 buf_T *
1526tv_get_buf(typval_T *tv, int curtab_only)
1527{
1528 char_u *name = tv->vval.v_string;
1529 buf_T *buf;
1530
1531 if (tv->v_type == VAR_NUMBER)
1532 return buflist_findnr((int)tv->vval.v_number);
1533 if (tv->v_type != VAR_STRING)
1534 return NULL;
1535 if (name == NULL || *name == NUL)
1536 return curbuf;
1537 if (name[0] == '$' && name[1] == NUL)
1538 return lastbuf;
1539
1540 buf = buflist_find_by_name(name, curtab_only);
1541
1542 // If not found, try expanding the name, like done for bufexists().
1543 if (buf == NULL)
1544 buf = find_buffer(tv);
1545
1546 return buf;
1547}
1548
1549#endif // FEAT_EVAL