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