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