xref: /vim-8.2.3635/src/typval.c (revision 4490ec4e)
1 /* 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 *
23 alloc_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 *
34 alloc_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
53 free_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 	    case VAR_INSTR:
95 		break;
96 	}
97 	vim_free(varp);
98     }
99 }
100 
101 /*
102  * Free the memory for a variable value and set the value to NULL or 0.
103  */
104     void
105 clear_tv(typval_T *varp)
106 {
107     if (varp != NULL)
108     {
109 	switch (varp->v_type)
110 	{
111 	    case VAR_FUNC:
112 		func_unref(varp->vval.v_string);
113 		// FALLTHROUGH
114 	    case VAR_STRING:
115 		VIM_CLEAR(varp->vval.v_string);
116 		break;
117 	    case VAR_PARTIAL:
118 		partial_unref(varp->vval.v_partial);
119 		varp->vval.v_partial = NULL;
120 		break;
121 	    case VAR_BLOB:
122 		blob_unref(varp->vval.v_blob);
123 		varp->vval.v_blob = NULL;
124 		break;
125 	    case VAR_LIST:
126 		list_unref(varp->vval.v_list);
127 		varp->vval.v_list = NULL;
128 		break;
129 	    case VAR_DICT:
130 		dict_unref(varp->vval.v_dict);
131 		varp->vval.v_dict = NULL;
132 		break;
133 	    case VAR_NUMBER:
134 	    case VAR_BOOL:
135 	    case VAR_SPECIAL:
136 		varp->vval.v_number = 0;
137 		break;
138 	    case VAR_FLOAT:
139 #ifdef FEAT_FLOAT
140 		varp->vval.v_float = 0.0;
141 		break;
142 #endif
143 	    case VAR_JOB:
144 #ifdef FEAT_JOB_CHANNEL
145 		job_unref(varp->vval.v_job);
146 		varp->vval.v_job = NULL;
147 #endif
148 		break;
149 	    case VAR_CHANNEL:
150 #ifdef FEAT_JOB_CHANNEL
151 		channel_unref(varp->vval.v_channel);
152 		varp->vval.v_channel = NULL;
153 #endif
154 		break;
155 	    case VAR_INSTR:
156 		VIM_CLEAR(varp->vval.v_instr);
157 		break;
158 	    case VAR_UNKNOWN:
159 	    case VAR_ANY:
160 	    case VAR_VOID:
161 		break;
162 	}
163 	varp->v_lock = 0;
164     }
165 }
166 
167 /*
168  * Set the value of a variable to NULL without freeing items.
169  */
170     void
171 init_tv(typval_T *varp)
172 {
173     if (varp != NULL)
174 	CLEAR_POINTER(varp);
175 }
176 
177     static varnumber_T
178 tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
179 {
180     varnumber_T	n = 0L;
181 
182     switch (varp->v_type)
183     {
184 	case VAR_NUMBER:
185 	    if (in_vim9script() && want_bool && varp->vval.v_number != 0
186 						   && varp->vval.v_number != 1)
187 	    {
188 		semsg(_(e_using_number_as_bool_nr), varp->vval.v_number);
189 		break;
190 	    }
191 	    return varp->vval.v_number;
192 	case VAR_FLOAT:
193 #ifdef FEAT_FLOAT
194 	    emsg(_("E805: Using a Float as a Number"));
195 	    break;
196 #endif
197 	case VAR_FUNC:
198 	case VAR_PARTIAL:
199 	    emsg(_("E703: Using a Funcref as a Number"));
200 	    break;
201 	case VAR_STRING:
202 	    if (in_vim9script())
203 	    {
204 		emsg_using_string_as(varp, !want_bool);
205 		break;
206 	    }
207 	    if (varp->vval.v_string != NULL)
208 		vim_str2nr(varp->vval.v_string, NULL, NULL,
209 					    STR2NR_ALL, &n, NULL, 0, FALSE);
210 	    return n;
211 	case VAR_LIST:
212 	    emsg(_("E745: Using a List as a Number"));
213 	    break;
214 	case VAR_DICT:
215 	    emsg(_("E728: Using a Dictionary as a Number"));
216 	    break;
217 	case VAR_BOOL:
218 	case VAR_SPECIAL:
219 	    if (!want_bool && in_vim9script())
220 	    {
221 		if (varp->v_type == VAR_BOOL)
222 		    emsg(_(e_using_bool_as_number));
223 		else
224 		    emsg(_("E611: Using a Special as a Number"));
225 		break;
226 	    }
227 	    return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
228 	case VAR_JOB:
229 #ifdef FEAT_JOB_CHANNEL
230 	    emsg(_("E910: Using a Job as a Number"));
231 	    break;
232 #endif
233 	case VAR_CHANNEL:
234 #ifdef FEAT_JOB_CHANNEL
235 	    emsg(_("E913: Using a Channel as a Number"));
236 	    break;
237 #endif
238 	case VAR_BLOB:
239 	    emsg(_("E974: Using a Blob as a Number"));
240 	    break;
241 	case VAR_VOID:
242 	    emsg(_(e_cannot_use_void_value));
243 	    break;
244 	case VAR_UNKNOWN:
245 	case VAR_ANY:
246 	case VAR_INSTR:
247 	    internal_error_no_abort("tv_get_number(UNKNOWN)");
248 	    break;
249     }
250     if (denote == NULL)		// useful for values that must be unsigned
251 	n = -1;
252     else
253 	*denote = TRUE;
254     return n;
255 }
256 
257 /*
258  * Get the number value of a variable.
259  * If it is a String variable, uses vim_str2nr().
260  * For incompatible types, return 0.
261  * tv_get_number_chk() is similar to tv_get_number(), but informs the
262  * caller of incompatible types: it sets *denote to TRUE if "denote"
263  * is not NULL or returns -1 otherwise.
264  */
265     varnumber_T
266 tv_get_number(typval_T *varp)
267 {
268     int		error = FALSE;
269 
270     return tv_get_number_chk(varp, &error);	// return 0L on error
271 }
272 
273     varnumber_T
274 tv_get_number_chk(typval_T *varp, int *denote)
275 {
276     return tv_get_bool_or_number_chk(varp, denote, FALSE);
277 }
278 
279 /*
280  * Get the boolean value of "varp".  This is like tv_get_number_chk(),
281  * but in Vim9 script accepts Number (0 and 1) and Bool/Special.
282  */
283     varnumber_T
284 tv_get_bool(typval_T *varp)
285 {
286     return tv_get_bool_or_number_chk(varp, NULL, TRUE);
287 }
288 
289 /*
290  * Get the boolean value of "varp".  This is like tv_get_number_chk(),
291  * but in Vim9 script accepts Number and Bool.
292  */
293     varnumber_T
294 tv_get_bool_chk(typval_T *varp, int *denote)
295 {
296     return tv_get_bool_or_number_chk(varp, denote, TRUE);
297 }
298 
299 #if defined(FEAT_FLOAT) || defined(PROTO)
300     float_T
301 tv_get_float(typval_T *varp)
302 {
303     switch (varp->v_type)
304     {
305 	case VAR_NUMBER:
306 	    return (float_T)(varp->vval.v_number);
307 	case VAR_FLOAT:
308 	    return varp->vval.v_float;
309 	case VAR_FUNC:
310 	case VAR_PARTIAL:
311 	    emsg(_("E891: Using a Funcref as a Float"));
312 	    break;
313 	case VAR_STRING:
314 	    emsg(_("E892: Using a String as a Float"));
315 	    break;
316 	case VAR_LIST:
317 	    emsg(_("E893: Using a List as a Float"));
318 	    break;
319 	case VAR_DICT:
320 	    emsg(_("E894: Using a Dictionary as a Float"));
321 	    break;
322 	case VAR_BOOL:
323 	    emsg(_("E362: Using a boolean value as a Float"));
324 	    break;
325 	case VAR_SPECIAL:
326 	    emsg(_("E907: Using a special value as a Float"));
327 	    break;
328 	case VAR_JOB:
329 # ifdef FEAT_JOB_CHANNEL
330 	    emsg(_("E911: Using a Job as a Float"));
331 	    break;
332 # endif
333 	case VAR_CHANNEL:
334 # ifdef FEAT_JOB_CHANNEL
335 	    emsg(_("E914: Using a Channel as a Float"));
336 	    break;
337 # endif
338 	case VAR_BLOB:
339 	    emsg(_("E975: Using a Blob as a Float"));
340 	    break;
341 	case VAR_VOID:
342 	    emsg(_(e_cannot_use_void_value));
343 	    break;
344 	case VAR_UNKNOWN:
345 	case VAR_ANY:
346 	case VAR_INSTR:
347 	    internal_error_no_abort("tv_get_float(UNKNOWN)");
348 	    break;
349     }
350     return 0;
351 }
352 #endif
353 
354 /*
355  * Give an error and return FAIL unless "args[idx]" is a string.
356  */
357     int
358 check_for_string_arg(typval_T *args, int idx)
359 {
360     if (args[idx].v_type != VAR_STRING)
361     {
362 	if (idx >= 0)
363 	    semsg(_(e_string_required_for_argument_nr), idx + 1);
364 	else
365 	    emsg(_(e_stringreq));
366 	return FAIL;
367     }
368     return OK;
369 }
370 
371 /*
372  * Give an error and return FAIL unless "args[idx]" is a non-empty string.
373  */
374     int
375 check_for_nonempty_string_arg(typval_T *args, int idx)
376 {
377     if (check_for_string_arg(args, idx) == FAIL)
378 	return FAIL;
379     if (args[idx].vval.v_string == NULL || *args[idx].vval.v_string == NUL)
380     {
381 	semsg(_(e_non_empty_string_required_for_argument_nr), idx + 1);
382 	return FAIL;
383     }
384     return OK;
385 }
386 
387 /*
388  * Check for an optional string argument at 'idx'
389  */
390     int
391 check_for_opt_string_arg(typval_T *args, int idx)
392 {
393     return (args[idx].v_type == VAR_UNKNOWN
394 	    || check_for_string_arg(args, idx) != FAIL);
395 }
396 
397 /*
398  * Give an error and return FAIL unless "args[idx]" is a number.
399  */
400     int
401 check_for_number_arg(typval_T *args, int idx)
402 {
403     if (args[idx].v_type != VAR_NUMBER)
404     {
405 	if (idx >= 0)
406 	    semsg(_(e_number_required_for_argument_nr), idx + 1);
407 	else
408 	    emsg(_(e_numberreq));
409 	return FAIL;
410     }
411     return OK;
412 }
413 
414 /*
415  * Check for an optional number argument at 'idx'
416  */
417     int
418 check_for_opt_number_arg(typval_T *args, int idx)
419 {
420     return (args[idx].v_type == VAR_UNKNOWN
421 	    || check_for_number_arg(args, idx) != FAIL);
422 }
423 
424 /*
425  * Give an error and return FAIL unless "args[idx]" is a float or a number.
426  */
427     int
428 check_for_float_or_nr_arg(typval_T *args, int idx)
429 {
430     if (args[idx].v_type != VAR_FLOAT && args[idx].v_type != VAR_NUMBER)
431     {
432 	if (idx >= 0)
433 	    semsg(_(e_float_or_number_required_for_argument_nr), idx + 1);
434 	else
435 	    emsg(_(e_numberreq));
436 	return FAIL;
437     }
438     return OK;
439 }
440 
441 /*
442  * Give an error and return FAIL unless "args[idx]" is a bool.
443  */
444     int
445 check_for_bool_arg(typval_T *args, int idx)
446 {
447     if (args[idx].v_type != VAR_BOOL
448 	    && !(args[idx].v_type == VAR_NUMBER
449 		&& (args[idx].vval.v_number == 0
450 		    || args[idx].vval.v_number == 1)))
451     {
452 	if (idx >= 0)
453 	    semsg(_(e_bool_required_for_argument_nr), idx + 1);
454 	else
455 	    emsg(_(e_boolreq));
456 	return FAIL;
457     }
458     return OK;
459 }
460 
461 /*
462  * Check for an optional bool argument at 'idx'
463  */
464     int
465 check_for_opt_bool_arg(typval_T *args, int idx)
466 {
467     return (args[idx].v_type == VAR_UNKNOWN
468 	    || check_for_bool_arg(args, idx) != FAIL);
469 }
470 
471 /*
472  * Give an error and return FAIL unless "args[idx]" is a list.
473  */
474     int
475 check_for_list_arg(typval_T *args, int idx)
476 {
477     if (args[idx].v_type != VAR_LIST)
478     {
479 	if (idx >= 0)
480 	    semsg(_(e_list_required_for_argument_nr), idx + 1);
481 	else
482 	    emsg(_(e_listreq));
483 	return FAIL;
484     }
485     return OK;
486 }
487 
488 /*
489  * Check for an optional list argument at 'idx'
490  */
491     int
492 check_for_opt_list_arg(typval_T *args, int idx)
493 {
494     return (args[idx].v_type == VAR_UNKNOWN
495 	    || check_for_list_arg(args, idx) != FAIL);
496 }
497 
498 /*
499  * Give an error and return FAIL unless "args[idx]" is a dict.
500  */
501     int
502 check_for_dict_arg(typval_T *args, int idx)
503 {
504     if (args[idx].v_type != VAR_DICT)
505     {
506 	if (idx >= 0)
507 	    semsg(_(e_dict_required_for_argument_nr), idx + 1);
508 	else
509 	    emsg(_(e_dictreq));
510 	return FAIL;
511     }
512     return OK;
513 }
514 
515 /*
516  * Check for an optional dict argument at 'idx'
517  */
518     int
519 check_for_opt_dict_arg(typval_T *args, int idx)
520 {
521     return (args[idx].v_type == VAR_UNKNOWN
522 	    || check_for_dict_arg(args, idx) != FAIL);
523 }
524 
525 /*
526  * Give an error and return FAIL unless "args[idx]" is a channel or a job.
527  */
528     int
529 check_for_chan_or_job_arg(typval_T *args, int idx)
530 {
531     if (args[idx].v_type != VAR_CHANNEL && args[idx].v_type != VAR_JOB)
532     {
533 	if (idx >= 0)
534 	    semsg(_(e_chan_or_job_required_for_argument_nr), idx + 1);
535 	else
536 	    emsg(_(e_chan_or_job_req));
537 	return FAIL;
538     }
539     return OK;
540 }
541 
542 /*
543  * Give an error and return FAIL unless "args[idx]" is an optional channel or a
544  * job.
545  */
546     int
547 check_for_opt_chan_or_job_arg(typval_T *args, int idx)
548 {
549     return (args[idx].v_type == VAR_UNKNOWN
550 	    || check_for_chan_or_job_arg(args, idx) != FAIL);
551 }
552 
553 /*
554  * Give an error and return FAIL unless "args[idx]" is a job.
555  */
556     int
557 check_for_job_arg(typval_T *args, int idx)
558 {
559     if (args[idx].v_type != VAR_JOB)
560     {
561 	if (idx >= 0)
562 	    semsg(_(e_job_required_for_argument_nr), idx + 1);
563 	else
564 	    emsg(_(e_jobreq));
565 	return FAIL;
566     }
567     return OK;
568 }
569 
570 /*
571  * Check for an optional job argument at 'idx'.
572  */
573     int
574 check_for_opt_job_arg(typval_T *args, int idx)
575 {
576     return (args[idx].v_type == VAR_UNKNOWN
577 	    || check_for_job_arg(args, idx) != FAIL);
578 }
579 
580 /*
581  * Give an error and return FAIL unless "args[idx]" is a string or
582  * a number.
583  */
584     int
585 check_for_string_or_number_arg(typval_T *args, int idx)
586 {
587     if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
588     {
589 	if (idx >= 0)
590 	    semsg(_(e_string_or_number_required_for_argument_nr), idx + 1);
591 	else
592 	    emsg(_(e_stringreq));
593 	return FAIL;
594     }
595     return OK;
596 }
597 
598 /*
599  * Check for an optional string or number argument at 'idx'.
600  */
601     int
602 check_for_opt_string_or_number_arg(typval_T *args, int idx)
603 {
604     return (args[idx].v_type == VAR_UNKNOWN
605 	    || check_for_string_or_number_arg(args, idx) != FAIL);
606 }
607 
608 /*
609  * Give an error and return FAIL unless "args[idx]" is a buffer number.
610  * Buffer number can be a number or a string.
611  */
612     int
613 check_for_buffer_arg(typval_T *args, int idx)
614 {
615     return check_for_string_or_number_arg(args, idx);
616 }
617 
618 /*
619  * Check for an optional buffer argument at 'idx'
620  */
621     int
622 check_for_opt_buffer_arg(typval_T *args, int idx)
623 {
624     return (args[idx].v_type == VAR_UNKNOWN
625 	    || check_for_buffer_arg(args, idx));
626 }
627 
628 /*
629  * Give an error and return FAIL unless "args[idx]" is a line number.
630  * Line number can be a number or a string.
631  */
632     int
633 check_for_lnum_arg(typval_T *args, int idx)
634 {
635     return check_for_string_or_number_arg(args, idx);
636 }
637 
638 /*
639  * Check for an optional line number argument at 'idx'
640  */
641     int
642 check_for_opt_lnum_arg(typval_T *args, int idx)
643 {
644     return (args[idx].v_type == VAR_UNKNOWN
645 	    || check_for_lnum_arg(args, idx));
646 }
647 
648 /*
649  * Give an error and return FAIL unless "args[idx]" is a string or a blob.
650  */
651     int
652 check_for_string_or_blob_arg(typval_T *args, int idx)
653 {
654     if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_BLOB)
655     {
656 	if (idx >= 0)
657 	    semsg(_(e_string_or_blob_required_for_argument_nr), idx + 1);
658 	else
659 	    emsg(_(e_stringreq));
660 	return FAIL;
661     }
662     return OK;
663 }
664 
665 /*
666  * Give an error and return FAIL unless "args[idx]" is a string or a list.
667  */
668     int
669 check_for_string_or_list_arg(typval_T *args, int idx)
670 {
671     if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_LIST)
672     {
673 	if (idx >= 0)
674 	    semsg(_(e_string_or_list_required_for_argument_nr), idx + 1);
675 	else
676 	    emsg(_(e_stringreq));
677 	return FAIL;
678     }
679     return OK;
680 }
681 
682 /*
683  * Check for an optional string or list argument at 'idx'
684  */
685     int
686 check_for_opt_string_or_list_arg(typval_T *args, int idx)
687 {
688     return (args[idx].v_type == VAR_UNKNOWN
689 	    || check_for_string_or_list_arg(args, idx));
690 }
691 
692 /*
693  * Give an error and return FAIL unless "args[idx]" is a string or a dict.
694  */
695     int
696 check_for_string_or_dict_arg(typval_T *args, int idx)
697 {
698     if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_DICT)
699     {
700 	if (idx >= 0)
701 	    semsg(_(e_string_or_dict_required_for_argument_nr), idx + 1);
702 	else
703 	    emsg(_(e_stringreq));
704 	return FAIL;
705     }
706     return OK;
707 }
708 
709 /*
710  * Give an error and return FAIL unless "args[idx]" is a string or a number
711  * or a list.
712  */
713     int
714 check_for_string_or_number_or_list_arg(typval_T *args, int idx)
715 {
716     if (args[idx].v_type != VAR_STRING
717 	    && args[idx].v_type != VAR_NUMBER
718 	    && args[idx].v_type != VAR_LIST)
719     {
720 	if (idx >= 0)
721 	    semsg(_(e_string_or_number_or_list_required_for_argument_nr), idx + 1);
722 	else
723 	    emsg(_(e_stringreq));
724 	return FAIL;
725     }
726     return OK;
727 }
728 
729 /*
730  * Give an error and return FAIL unless "args[idx]" is a string or a list
731  * or a dict.
732  */
733     int
734 check_for_string_or_list_or_dict_arg(typval_T *args, int idx)
735 {
736     if (args[idx].v_type != VAR_STRING
737 	    && args[idx].v_type != VAR_LIST
738 	    && args[idx].v_type != VAR_DICT)
739     {
740 	if (idx >= 0)
741 	    semsg(_(e_string_or_list_or_dict_required_for_argument_nr), idx + 1);
742 	else
743 	    emsg(_(e_stringreq));
744 	return FAIL;
745     }
746     return OK;
747 }
748 
749 /*
750  * Give an error and return FAIL unless "args[idx]" is a list or a blob.
751  */
752     int
753 check_for_list_or_blob_arg(typval_T *args, int idx)
754 {
755     if (args[idx].v_type != VAR_LIST && args[idx].v_type != VAR_BLOB)
756     {
757 	if (idx >= 0)
758 	    semsg(_(e_list_or_blob_required_for_argument_nr), idx + 1);
759 	else
760 	    emsg(_(e_listreq));
761 	return FAIL;
762     }
763     return OK;
764 }
765 
766 /*
767  * Give an error and return FAIL unless "args[idx]" is a list or dict
768  */
769     int
770 check_for_list_or_dict_arg(typval_T *args, int idx)
771 {
772     if (args[idx].v_type != VAR_LIST
773 	    && args[idx].v_type != VAR_DICT)
774     {
775 	if (idx >= 0)
776 	    semsg(_(e_list_or_dict_required_for_argument_nr), idx + 1);
777 	else
778 	    emsg(_(e_listreq));
779 	return FAIL;
780     }
781     return OK;
782 }
783 
784 /*
785  * Give an error and return FAIL unless "args[idx]" is a list or dict or a
786  * blob.
787  */
788     int
789 check_for_list_or_dict_or_blob_arg(typval_T *args, int idx)
790 {
791     if (args[idx].v_type != VAR_LIST
792 	    && args[idx].v_type != VAR_DICT
793 	    && args[idx].v_type != VAR_BLOB)
794     {
795 	if (idx >= 0)
796 	    semsg(_(e_list_or_dict_or_blob_required_for_argument_nr), idx + 1);
797 	else
798 	    emsg(_(e_listreq));
799 	return FAIL;
800     }
801     return OK;
802 }
803 
804 /*
805  * Give an error and return FAIL unless "args[idx]" is an optional buffer
806  * number or a dict.
807  */
808     int
809 check_for_opt_buffer_or_dict_arg(typval_T *args, int idx)
810 {
811     if (args[idx].v_type != VAR_UNKNOWN
812 	    && args[idx].v_type != VAR_STRING
813 	    && args[idx].v_type != VAR_NUMBER
814 	    && args[idx].v_type != VAR_DICT)
815     {
816 	if (idx >= 0)
817 	    semsg(_(e_string_required_for_argument_nr), idx + 1);
818 	else
819 	    emsg(_(e_stringreq));
820 	return FAIL;
821     }
822     return OK;
823 }
824 
825 /*
826  * Get the string value of a variable.
827  * If it is a Number variable, the number is converted into a string.
828  * tv_get_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
829  * tv_get_string_buf() uses a given buffer.
830  * If the String variable has never been set, return an empty string.
831  * Never returns NULL;
832  * tv_get_string_chk() and tv_get_string_buf_chk() are similar, but return
833  * NULL on error.
834  */
835     char_u *
836 tv_get_string(typval_T *varp)
837 {
838     static char_u   mybuf[NUMBUFLEN];
839 
840     return tv_get_string_buf(varp, mybuf);
841 }
842 
843 /*
844  * Like tv_get_string() but don't allow number to string conversion for Vim9.
845  */
846     char_u *
847 tv_get_string_strict(typval_T *varp)
848 {
849     static char_u   mybuf[NUMBUFLEN];
850     char_u	    *res =  tv_get_string_buf_chk_strict(
851 						 varp, mybuf, in_vim9script());
852 
853     return res != NULL ? res : (char_u *)"";
854 }
855 
856     char_u *
857 tv_get_string_buf(typval_T *varp, char_u *buf)
858 {
859     char_u	*res = tv_get_string_buf_chk(varp, buf);
860 
861     return res != NULL ? res : (char_u *)"";
862 }
863 
864 /*
865  * Careful: This uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
866  */
867     char_u *
868 tv_get_string_chk(typval_T *varp)
869 {
870     static char_u   mybuf[NUMBUFLEN];
871 
872     return tv_get_string_buf_chk(varp, mybuf);
873 }
874 
875     char_u *
876 tv_get_string_buf_chk(typval_T *varp, char_u *buf)
877 {
878     return tv_get_string_buf_chk_strict(varp, buf, FALSE);
879 }
880 
881     char_u *
882 tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
883 {
884     switch (varp->v_type)
885     {
886 	case VAR_NUMBER:
887 	    if (strict)
888 	    {
889 		emsg(_(e_using_number_as_string));
890 		break;
891 	    }
892 	    vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
893 					    (varnumber_T)varp->vval.v_number);
894 	    return buf;
895 	case VAR_FUNC:
896 	case VAR_PARTIAL:
897 	    emsg(_("E729: Using a Funcref as a String"));
898 	    break;
899 	case VAR_LIST:
900 	    emsg(_("E730: Using a List as a String"));
901 	    break;
902 	case VAR_DICT:
903 	    emsg(_("E731: Using a Dictionary as a String"));
904 	    break;
905 	case VAR_FLOAT:
906 #ifdef FEAT_FLOAT
907 	    if (strict)
908 	    {
909 		emsg(_(e_float_as_string));
910 		break;
911 	    }
912 	    vim_snprintf((char *)buf, NUMBUFLEN, "%g", varp->vval.v_float);
913 	    return buf;
914 #endif
915 	case VAR_STRING:
916 	    if (varp->vval.v_string != NULL)
917 		return varp->vval.v_string;
918 	    return (char_u *)"";
919 	case VAR_BOOL:
920 	case VAR_SPECIAL:
921 	    STRCPY(buf, get_var_special_name(varp->vval.v_number));
922 	    return buf;
923         case VAR_BLOB:
924 	    emsg(_("E976: Using a Blob as a String"));
925 	    break;
926 	case VAR_JOB:
927 #ifdef FEAT_JOB_CHANNEL
928 	    if (in_vim9script())
929 	    {
930 		semsg(_(e_using_invalid_value_as_string_str), "job");
931 		break;
932 	    }
933 	    return job_to_string_buf(varp, buf);
934 #endif
935 	    break;
936 	case VAR_CHANNEL:
937 #ifdef FEAT_JOB_CHANNEL
938 	    if (in_vim9script())
939 	    {
940 		semsg(_(e_using_invalid_value_as_string_str), "channel");
941 		break;
942 	    }
943 	    return channel_to_string_buf(varp, buf);
944 #endif
945 	    break;
946 	case VAR_VOID:
947 	    emsg(_(e_cannot_use_void_value));
948 	    break;
949 	case VAR_UNKNOWN:
950 	case VAR_ANY:
951 	case VAR_INSTR:
952 	    semsg(_(e_using_invalid_value_as_string_str),
953 						  vartype_name(varp->v_type));
954 	    break;
955     }
956     return NULL;
957 }
958 
959 /*
960  * Turn a typeval into a string.  Similar to tv_get_string_buf() but uses
961  * string() on Dict, List, etc.
962  */
963     char_u *
964 tv_stringify(typval_T *varp, char_u *buf)
965 {
966     if (varp->v_type == VAR_LIST
967 	    || varp->v_type == VAR_DICT
968 	    || varp->v_type == VAR_BLOB
969 	    || varp->v_type == VAR_FUNC
970 	    || varp->v_type == VAR_PARTIAL
971 	    || varp->v_type == VAR_FLOAT)
972     {
973 	typval_T tmp;
974 
975 	f_string(varp, &tmp);
976 	tv_get_string_buf(&tmp, buf);
977 	clear_tv(varp);
978 	*varp = tmp;
979 	return tmp.vval.v_string;
980     }
981     return tv_get_string_buf(varp, buf);
982 }
983 
984 /*
985  * Return TRUE if typeval "tv" and its value are set to be locked (immutable).
986  * Also give an error message, using "name" or _("name") when use_gettext is
987  * TRUE.
988  */
989     int
990 tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
991 {
992     int	lock = 0;
993 
994     switch (tv->v_type)
995     {
996 	case VAR_BLOB:
997 	    if (tv->vval.v_blob != NULL)
998 		lock = tv->vval.v_blob->bv_lock;
999 	    break;
1000 	case VAR_LIST:
1001 	    if (tv->vval.v_list != NULL)
1002 		lock = tv->vval.v_list->lv_lock;
1003 	    break;
1004 	case VAR_DICT:
1005 	    if (tv->vval.v_dict != NULL)
1006 		lock = tv->vval.v_dict->dv_lock;
1007 	    break;
1008 	default:
1009 	    break;
1010     }
1011     return value_check_lock(tv->v_lock, name, use_gettext)
1012 		   || (lock != 0 && value_check_lock(lock, name, use_gettext));
1013 }
1014 
1015 /*
1016  * Copy the values from typval_T "from" to typval_T "to".
1017  * When needed allocates string or increases reference count.
1018  * Does not make a copy of a list, blob or dict but copies the reference!
1019  * It is OK for "from" and "to" to point to the same item.  This is used to
1020  * make a copy later.
1021  */
1022     void
1023 copy_tv(typval_T *from, typval_T *to)
1024 {
1025     to->v_type = from->v_type;
1026     to->v_lock = 0;
1027     switch (from->v_type)
1028     {
1029 	case VAR_NUMBER:
1030 	case VAR_BOOL:
1031 	case VAR_SPECIAL:
1032 	    to->vval.v_number = from->vval.v_number;
1033 	    break;
1034 	case VAR_FLOAT:
1035 #ifdef FEAT_FLOAT
1036 	    to->vval.v_float = from->vval.v_float;
1037 	    break;
1038 #endif
1039 	case VAR_JOB:
1040 #ifdef FEAT_JOB_CHANNEL
1041 	    to->vval.v_job = from->vval.v_job;
1042 	    if (to->vval.v_job != NULL)
1043 		++to->vval.v_job->jv_refcount;
1044 	    break;
1045 #endif
1046 	case VAR_CHANNEL:
1047 #ifdef FEAT_JOB_CHANNEL
1048 	    to->vval.v_channel = from->vval.v_channel;
1049 	    if (to->vval.v_channel != NULL)
1050 		++to->vval.v_channel->ch_refcount;
1051 	    break;
1052 #endif
1053 	case VAR_INSTR:
1054 	    to->vval.v_instr = from->vval.v_instr;
1055 	    break;
1056 
1057 	case VAR_STRING:
1058 	case VAR_FUNC:
1059 	    if (from->vval.v_string == NULL)
1060 		to->vval.v_string = NULL;
1061 	    else
1062 	    {
1063 		to->vval.v_string = vim_strsave(from->vval.v_string);
1064 		if (from->v_type == VAR_FUNC)
1065 		    func_ref(to->vval.v_string);
1066 	    }
1067 	    break;
1068 	case VAR_PARTIAL:
1069 	    if (from->vval.v_partial == NULL)
1070 		to->vval.v_partial = NULL;
1071 	    else
1072 	    {
1073 		to->vval.v_partial = from->vval.v_partial;
1074 		++to->vval.v_partial->pt_refcount;
1075 	    }
1076 	    break;
1077 	case VAR_BLOB:
1078 	    if (from->vval.v_blob == NULL)
1079 		to->vval.v_blob = NULL;
1080 	    else
1081 	    {
1082 		to->vval.v_blob = from->vval.v_blob;
1083 		++to->vval.v_blob->bv_refcount;
1084 	    }
1085 	    break;
1086 	case VAR_LIST:
1087 	    if (from->vval.v_list == NULL)
1088 		to->vval.v_list = NULL;
1089 	    else
1090 	    {
1091 		to->vval.v_list = from->vval.v_list;
1092 		++to->vval.v_list->lv_refcount;
1093 	    }
1094 	    break;
1095 	case VAR_DICT:
1096 	    if (from->vval.v_dict == NULL)
1097 		to->vval.v_dict = NULL;
1098 	    else
1099 	    {
1100 		to->vval.v_dict = from->vval.v_dict;
1101 		++to->vval.v_dict->dv_refcount;
1102 	    }
1103 	    break;
1104 	case VAR_VOID:
1105 	    emsg(_(e_cannot_use_void_value));
1106 	    break;
1107 	case VAR_UNKNOWN:
1108 	case VAR_ANY:
1109 	    internal_error_no_abort("copy_tv(UNKNOWN)");
1110 	    break;
1111     }
1112 }
1113 
1114 /*
1115  * Compare "typ1" and "typ2".  Put the result in "typ1".
1116  */
1117     int
1118 typval_compare(
1119     typval_T	*typ1,   // first operand
1120     typval_T	*typ2,   // second operand
1121     exprtype_T	type,    // operator
1122     int		ic)      // ignore case
1123 {
1124     int		i;
1125     varnumber_T	n1, n2;
1126     char_u	*s1, *s2;
1127     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1128     int		type_is = type == EXPR_IS || type == EXPR_ISNOT;
1129 
1130     if (type_is && typ1->v_type != typ2->v_type)
1131     {
1132 	// For "is" a different type always means FALSE, for "notis"
1133 	// it means TRUE.
1134 	n1 = (type == EXPR_ISNOT);
1135     }
1136     else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
1137     {
1138 	if (type_is)
1139 	{
1140 	    n1 = (typ1->v_type == typ2->v_type
1141 			    && typ1->vval.v_blob == typ2->vval.v_blob);
1142 	    if (type == EXPR_ISNOT)
1143 		n1 = !n1;
1144 	}
1145 	else if (typ1->v_type != typ2->v_type
1146 		|| (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1147 	{
1148 	    if (typ1->v_type != typ2->v_type)
1149 		emsg(_("E977: Can only compare Blob with Blob"));
1150 	    else
1151 		emsg(_(e_invalblob));
1152 	    clear_tv(typ1);
1153 	    return FAIL;
1154 	}
1155 	else
1156 	{
1157 	    // Compare two Blobs for being equal or unequal.
1158 	    n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
1159 	    if (type == EXPR_NEQUAL)
1160 		n1 = !n1;
1161 	}
1162     }
1163     else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
1164     {
1165 	if (type_is)
1166 	{
1167 	    n1 = (typ1->v_type == typ2->v_type
1168 			    && typ1->vval.v_list == typ2->vval.v_list);
1169 	    if (type == EXPR_ISNOT)
1170 		n1 = !n1;
1171 	}
1172 	else if (typ1->v_type != typ2->v_type
1173 		|| (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1174 	{
1175 	    if (typ1->v_type != typ2->v_type)
1176 		emsg(_("E691: Can only compare List with List"));
1177 	    else
1178 		emsg(_("E692: Invalid operation for List"));
1179 	    clear_tv(typ1);
1180 	    return FAIL;
1181 	}
1182 	else
1183 	{
1184 	    // Compare two Lists for being equal or unequal.
1185 	    n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
1186 							    ic, FALSE);
1187 	    if (type == EXPR_NEQUAL)
1188 		n1 = !n1;
1189 	}
1190     }
1191 
1192     else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
1193     {
1194 	if (type_is)
1195 	{
1196 	    n1 = (typ1->v_type == typ2->v_type
1197 			    && typ1->vval.v_dict == typ2->vval.v_dict);
1198 	    if (type == EXPR_ISNOT)
1199 		n1 = !n1;
1200 	}
1201 	else if (typ1->v_type != typ2->v_type
1202 		|| (type != EXPR_EQUAL && type != EXPR_NEQUAL))
1203 	{
1204 	    if (typ1->v_type != typ2->v_type)
1205 		emsg(_("E735: Can only compare Dictionary with Dictionary"));
1206 	    else
1207 		emsg(_("E736: Invalid operation for Dictionary"));
1208 	    clear_tv(typ1);
1209 	    return FAIL;
1210 	}
1211 	else
1212 	{
1213 	    // Compare two Dictionaries for being equal or unequal.
1214 	    n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
1215 							    ic, FALSE);
1216 	    if (type == EXPR_NEQUAL)
1217 		n1 = !n1;
1218 	}
1219     }
1220 
1221     else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
1222 	|| typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
1223     {
1224 	if (type != EXPR_EQUAL && type != EXPR_NEQUAL
1225 		&& type != EXPR_IS && type != EXPR_ISNOT)
1226 	{
1227 	    emsg(_("E694: Invalid operation for Funcrefs"));
1228 	    clear_tv(typ1);
1229 	    return FAIL;
1230 	}
1231 	if ((typ1->v_type == VAR_PARTIAL
1232 					&& typ1->vval.v_partial == NULL)
1233 		|| (typ2->v_type == VAR_PARTIAL
1234 					&& typ2->vval.v_partial == NULL))
1235 	    // When both partials are NULL, then they are equal.
1236 	    // Otherwise they are not equal.
1237 	    n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
1238 	else if (type_is)
1239 	{
1240 	    if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
1241 		// strings are considered the same if their value is
1242 		// the same
1243 		n1 = tv_equal(typ1, typ2, ic, FALSE);
1244 	    else if (typ1->v_type == VAR_PARTIAL
1245 					&& typ2->v_type == VAR_PARTIAL)
1246 		n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
1247 	    else
1248 		n1 = FALSE;
1249 	}
1250 	else
1251 	    n1 = tv_equal(typ1, typ2, ic, FALSE);
1252 	if (type == EXPR_NEQUAL || type == EXPR_ISNOT)
1253 	    n1 = !n1;
1254     }
1255 
1256 #ifdef FEAT_FLOAT
1257     // If one of the two variables is a float, compare as a float.
1258     // When using "=~" or "!~", always compare as string.
1259     else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
1260 	    && type != EXPR_MATCH && type != EXPR_NOMATCH)
1261     {
1262 	float_T f1, f2;
1263 
1264 	f1 = tv_get_float(typ1);
1265 	f2 = tv_get_float(typ2);
1266 	n1 = FALSE;
1267 	switch (type)
1268 	{
1269 	    case EXPR_IS:
1270 	    case EXPR_EQUAL:    n1 = (f1 == f2); break;
1271 	    case EXPR_ISNOT:
1272 	    case EXPR_NEQUAL:   n1 = (f1 != f2); break;
1273 	    case EXPR_GREATER:  n1 = (f1 > f2); break;
1274 	    case EXPR_GEQUAL:   n1 = (f1 >= f2); break;
1275 	    case EXPR_SMALLER:  n1 = (f1 < f2); break;
1276 	    case EXPR_SEQUAL:   n1 = (f1 <= f2); break;
1277 	    case EXPR_UNKNOWN:
1278 	    case EXPR_MATCH:
1279 	    default:  break;  // avoid gcc warning
1280 	}
1281     }
1282 #endif
1283 
1284     // If one of the two variables is a number, compare as a number.
1285     // When using "=~" or "!~", always compare as string.
1286     else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
1287 	    && type != EXPR_MATCH && type != EXPR_NOMATCH)
1288     {
1289 	n1 = tv_get_number(typ1);
1290 	n2 = tv_get_number(typ2);
1291 	switch (type)
1292 	{
1293 	    case EXPR_IS:
1294 	    case EXPR_EQUAL:    n1 = (n1 == n2); break;
1295 	    case EXPR_ISNOT:
1296 	    case EXPR_NEQUAL:   n1 = (n1 != n2); break;
1297 	    case EXPR_GREATER:  n1 = (n1 > n2); break;
1298 	    case EXPR_GEQUAL:   n1 = (n1 >= n2); break;
1299 	    case EXPR_SMALLER:  n1 = (n1 < n2); break;
1300 	    case EXPR_SEQUAL:   n1 = (n1 <= n2); break;
1301 	    case EXPR_UNKNOWN:
1302 	    case EXPR_MATCH:
1303 	    default:  break;  // avoid gcc warning
1304 	}
1305     }
1306     else if (in_vim9script() && (typ1->v_type == VAR_BOOL
1307 				    || typ2->v_type == VAR_BOOL
1308 				    || (typ1->v_type == VAR_SPECIAL
1309 					      && typ2->v_type == VAR_SPECIAL)))
1310     {
1311 	if (typ1->v_type != typ2->v_type)
1312 	{
1313 	    semsg(_(e_cannot_compare_str_with_str),
1314 		       vartype_name(typ1->v_type), vartype_name(typ2->v_type));
1315 	    clear_tv(typ1);
1316 	    return FAIL;
1317 	}
1318 	n1 = typ1->vval.v_number;
1319 	n2 = typ2->vval.v_number;
1320 	switch (type)
1321 	{
1322 	    case EXPR_IS:
1323 	    case EXPR_EQUAL:    n1 = (n1 == n2); break;
1324 	    case EXPR_ISNOT:
1325 	    case EXPR_NEQUAL:   n1 = (n1 != n2); break;
1326 	    default:
1327 		semsg(_(e_invalid_operation_for_str),
1328 						   vartype_name(typ1->v_type));
1329 		clear_tv(typ1);
1330 		return FAIL;
1331 	}
1332     }
1333     else
1334     {
1335 	if (in_vim9script()
1336 	      && ((typ1->v_type != VAR_STRING && typ1->v_type != VAR_SPECIAL)
1337 	       || (typ2->v_type != VAR_STRING && typ2->v_type != VAR_SPECIAL)))
1338 	{
1339 	    semsg(_(e_cannot_compare_str_with_str),
1340 		       vartype_name(typ1->v_type), vartype_name(typ2->v_type));
1341 	    clear_tv(typ1);
1342 	    return FAIL;
1343 	}
1344 	s1 = tv_get_string_buf(typ1, buf1);
1345 	s2 = tv_get_string_buf(typ2, buf2);
1346 	if (type != EXPR_MATCH && type != EXPR_NOMATCH)
1347 	    i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
1348 	else
1349 	    i = 0;
1350 	n1 = FALSE;
1351 	switch (type)
1352 	{
1353 	    case EXPR_IS:
1354 	    case EXPR_EQUAL:    n1 = (i == 0); break;
1355 	    case EXPR_ISNOT:
1356 	    case EXPR_NEQUAL:   n1 = (i != 0); break;
1357 	    case EXPR_GREATER:  n1 = (i > 0); break;
1358 	    case EXPR_GEQUAL:   n1 = (i >= 0); break;
1359 	    case EXPR_SMALLER:  n1 = (i < 0); break;
1360 	    case EXPR_SEQUAL:   n1 = (i <= 0); break;
1361 
1362 	    case EXPR_MATCH:
1363 	    case EXPR_NOMATCH:
1364 		    n1 = pattern_match(s2, s1, ic);
1365 		    if (type == EXPR_NOMATCH)
1366 			n1 = !n1;
1367 		    break;
1368 
1369 	    default:  break;  // avoid gcc warning
1370 	}
1371     }
1372     clear_tv(typ1);
1373     if (in_vim9script())
1374     {
1375 	typ1->v_type = VAR_BOOL;
1376 	typ1->vval.v_number = n1 ? VVAL_TRUE : VVAL_FALSE;
1377     }
1378     else
1379     {
1380 	typ1->v_type = VAR_NUMBER;
1381 	typ1->vval.v_number = n1;
1382     }
1383 
1384     return OK;
1385 }
1386 
1387 /*
1388  * Convert any type to a string, never give an error.
1389  * When "quotes" is TRUE add quotes to a string.
1390  * Returns an allocated string.
1391  */
1392     char_u *
1393 typval_tostring(typval_T *arg, int quotes)
1394 {
1395     char_u	*tofree;
1396     char_u	numbuf[NUMBUFLEN];
1397     char_u	*ret = NULL;
1398 
1399     if (arg == NULL)
1400 	return vim_strsave((char_u *)"(does not exist)");
1401     if (!quotes && arg->v_type == VAR_STRING)
1402     {
1403 	ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
1404 							 : arg->vval.v_string);
1405     }
1406     else
1407     {
1408 	ret = tv2string(arg, &tofree, numbuf, 0);
1409 	// Make a copy if we have a value but it's not in allocated memory.
1410 	if (ret != NULL && tofree == NULL)
1411 	    ret = vim_strsave(ret);
1412     }
1413     return ret;
1414 }
1415 
1416 /*
1417  * Return TRUE if typeval "tv" is locked: Either that value is locked itself
1418  * or it refers to a List or Dictionary that is locked.
1419  */
1420     int
1421 tv_islocked(typval_T *tv)
1422 {
1423     return (tv->v_lock & VAR_LOCKED)
1424 	|| (tv->v_type == VAR_LIST
1425 		&& tv->vval.v_list != NULL
1426 		&& (tv->vval.v_list->lv_lock & VAR_LOCKED))
1427 	|| (tv->v_type == VAR_DICT
1428 		&& tv->vval.v_dict != NULL
1429 		&& (tv->vval.v_dict->dv_lock & VAR_LOCKED));
1430 }
1431 
1432     static int
1433 func_equal(
1434     typval_T *tv1,
1435     typval_T *tv2,
1436     int	     ic)	    // ignore case
1437 {
1438     char_u	*s1, *s2;
1439     dict_T	*d1, *d2;
1440     int		a1, a2;
1441     int		i;
1442 
1443     // empty and NULL function name considered the same
1444     s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
1445 					   : partial_name(tv1->vval.v_partial);
1446     if (s1 != NULL && *s1 == NUL)
1447 	s1 = NULL;
1448     s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
1449 					   : partial_name(tv2->vval.v_partial);
1450     if (s2 != NULL && *s2 == NUL)
1451 	s2 = NULL;
1452     if (s1 == NULL || s2 == NULL)
1453     {
1454 	if (s1 != s2)
1455 	    return FALSE;
1456     }
1457     else if (STRCMP(s1, s2) != 0)
1458 	return FALSE;
1459 
1460     // empty dict and NULL dict is different
1461     d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
1462     d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
1463     if (d1 == NULL || d2 == NULL)
1464     {
1465 	if (d1 != d2)
1466 	    return FALSE;
1467     }
1468     else if (!dict_equal(d1, d2, ic, TRUE))
1469 	return FALSE;
1470 
1471     // empty list and no list considered the same
1472     a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
1473     a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
1474     if (a1 != a2)
1475 	return FALSE;
1476     for (i = 0; i < a1; ++i)
1477 	if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
1478 		      tv2->vval.v_partial->pt_argv + i, ic, TRUE))
1479 	    return FALSE;
1480 
1481     return TRUE;
1482 }
1483 
1484 /*
1485  * Return TRUE if "tv1" and "tv2" have the same value.
1486  * Compares the items just like "==" would compare them, but strings and
1487  * numbers are different.  Floats and numbers are also different.
1488  */
1489     int
1490 tv_equal(
1491     typval_T *tv1,
1492     typval_T *tv2,
1493     int	     ic,	    // ignore case
1494     int	     recursive)	    // TRUE when used recursively
1495 {
1496     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1497     char_u	*s1, *s2;
1498     static int  recursive_cnt = 0;	    // catch recursive loops
1499     int		r;
1500     static int	tv_equal_recurse_limit;
1501 
1502     // Catch lists and dicts that have an endless loop by limiting
1503     // recursiveness to a limit.  We guess they are equal then.
1504     // A fixed limit has the problem of still taking an awful long time.
1505     // Reduce the limit every time running into it. That should work fine for
1506     // deeply linked structures that are not recursively linked and catch
1507     // recursiveness quickly.
1508     if (!recursive)
1509 	tv_equal_recurse_limit = 1000;
1510     if (recursive_cnt >= tv_equal_recurse_limit)
1511     {
1512 	--tv_equal_recurse_limit;
1513 	return TRUE;
1514     }
1515 
1516     // For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and
1517     // arguments.
1518     if ((tv1->v_type == VAR_FUNC
1519 		|| (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
1520 	    && (tv2->v_type == VAR_FUNC
1521 		|| (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
1522     {
1523 	++recursive_cnt;
1524 	r = func_equal(tv1, tv2, ic);
1525 	--recursive_cnt;
1526 	return r;
1527     }
1528 
1529     if (tv1->v_type != tv2->v_type
1530 	    && ((tv1->v_type != VAR_BOOL && tv1->v_type != VAR_SPECIAL)
1531 		|| (tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL)))
1532 	return FALSE;
1533 
1534     switch (tv1->v_type)
1535     {
1536 	case VAR_LIST:
1537 	    ++recursive_cnt;
1538 	    r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
1539 	    --recursive_cnt;
1540 	    return r;
1541 
1542 	case VAR_DICT:
1543 	    ++recursive_cnt;
1544 	    r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
1545 	    --recursive_cnt;
1546 	    return r;
1547 
1548 	case VAR_BLOB:
1549 	    return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
1550 
1551 	case VAR_NUMBER:
1552 	case VAR_BOOL:
1553 	case VAR_SPECIAL:
1554 	    return tv1->vval.v_number == tv2->vval.v_number;
1555 
1556 	case VAR_STRING:
1557 	    s1 = tv_get_string_buf(tv1, buf1);
1558 	    s2 = tv_get_string_buf(tv2, buf2);
1559 	    return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
1560 
1561 	case VAR_FLOAT:
1562 #ifdef FEAT_FLOAT
1563 	    return tv1->vval.v_float == tv2->vval.v_float;
1564 #endif
1565 	case VAR_JOB:
1566 #ifdef FEAT_JOB_CHANNEL
1567 	    return tv1->vval.v_job == tv2->vval.v_job;
1568 #endif
1569 	case VAR_CHANNEL:
1570 #ifdef FEAT_JOB_CHANNEL
1571 	    return tv1->vval.v_channel == tv2->vval.v_channel;
1572 #endif
1573 	case VAR_INSTR:
1574 	    return tv1->vval.v_instr == tv2->vval.v_instr;
1575 
1576 	case VAR_PARTIAL:
1577 	    return tv1->vval.v_partial == tv2->vval.v_partial;
1578 
1579 	case VAR_FUNC:
1580 	    return tv1->vval.v_string == tv2->vval.v_string;
1581 
1582 	case VAR_UNKNOWN:
1583 	case VAR_ANY:
1584 	case VAR_VOID:
1585 	    break;
1586     }
1587 
1588     // VAR_UNKNOWN can be the result of a invalid expression, let's say it
1589     // does not equal anything, not even itself.
1590     return FALSE;
1591 }
1592 
1593 /*
1594  * Get an option value.
1595  * "arg" points to the '&' or '+' before the option name.
1596  * "arg" is advanced to character after the option name.
1597  * Return OK or FAIL.
1598  */
1599     int
1600 eval_option(
1601     char_u	**arg,
1602     typval_T	*rettv,	// when NULL, only check if option exists
1603     int		evaluate)
1604 {
1605     char_u	*option_end;
1606     long	numval;
1607     char_u	*stringval;
1608     getoption_T	opt_type;
1609     int		c;
1610     int		working = (**arg == '+');    // has("+option")
1611     int		ret = OK;
1612     int		opt_flags;
1613 
1614     // Isolate the option name and find its value.
1615     option_end = find_option_end(arg, &opt_flags);
1616     if (option_end == NULL)
1617     {
1618 	if (rettv != NULL)
1619 	    semsg(_("E112: Option name missing: %s"), *arg);
1620 	return FAIL;
1621     }
1622 
1623     if (!evaluate)
1624     {
1625 	*arg = option_end;
1626 	return OK;
1627     }
1628 
1629     c = *option_end;
1630     *option_end = NUL;
1631     opt_type = get_option_value(*arg, &numval,
1632 			       rettv == NULL ? NULL : &stringval, opt_flags);
1633 
1634     if (opt_type == gov_unknown)
1635     {
1636 	if (rettv != NULL)
1637 	    semsg(_(e_unknown_option), *arg);
1638 	ret = FAIL;
1639     }
1640     else if (rettv != NULL)
1641     {
1642 	rettv->v_lock = 0;
1643 	if (opt_type == gov_hidden_string)
1644 	{
1645 	    rettv->v_type = VAR_STRING;
1646 	    rettv->vval.v_string = NULL;
1647 	}
1648 	else if (opt_type == gov_hidden_bool || opt_type == gov_hidden_number)
1649 	{
1650 	    rettv->v_type = in_vim9script() && opt_type == gov_hidden_bool
1651 						       ? VAR_BOOL : VAR_NUMBER;
1652 	    rettv->vval.v_number = 0;
1653 	}
1654 	else if (opt_type == gov_bool || opt_type == gov_number)
1655 	{
1656 	    if (in_vim9script() && opt_type == gov_bool)
1657 	    {
1658 		rettv->v_type = VAR_BOOL;
1659 		rettv->vval.v_number = numval ? VVAL_TRUE : VVAL_FALSE;
1660 	    }
1661 	    else
1662 	    {
1663 		rettv->v_type = VAR_NUMBER;
1664 		rettv->vval.v_number = numval;
1665 	    }
1666 	}
1667 	else				// string option
1668 	{
1669 	    rettv->v_type = VAR_STRING;
1670 	    rettv->vval.v_string = stringval;
1671 	}
1672     }
1673     else if (working && (opt_type == gov_hidden_bool
1674 			|| opt_type == gov_hidden_number
1675 			|| opt_type == gov_hidden_string))
1676 	ret = FAIL;
1677 
1678     *option_end = c;		    // put back for error messages
1679     *arg = option_end;
1680 
1681     return ret;
1682 }
1683 
1684 /*
1685  * Allocate a variable for a number constant.  Also deals with "0z" for blob.
1686  * Return OK or FAIL.
1687  */
1688     int
1689 eval_number(
1690 	char_u	    **arg,
1691 	typval_T    *rettv,
1692 	int	    evaluate,
1693 	int	    want_string UNUSED)
1694 {
1695     int		len;
1696 #ifdef FEAT_FLOAT
1697     char_u	*p;
1698     int		get_float = FALSE;
1699 
1700     // We accept a float when the format matches
1701     // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?".  This is very
1702     // strict to avoid backwards compatibility problems.
1703     // With script version 2 and later the leading digit can be
1704     // omitted.
1705     // Don't look for a float after the "." operator, so that
1706     // ":let vers = 1.2.3" doesn't fail.
1707     if (**arg == '.')
1708 	p = *arg;
1709     else
1710 	p = skipdigits(*arg + 1);
1711     if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
1712     {
1713 	get_float = TRUE;
1714 	p = skipdigits(p + 2);
1715 	if (*p == 'e' || *p == 'E')
1716 	{
1717 	    ++p;
1718 	    if (*p == '-' || *p == '+')
1719 		++p;
1720 	    if (!vim_isdigit(*p))
1721 		get_float = FALSE;
1722 	    else
1723 		p = skipdigits(p + 1);
1724 	}
1725 	if (ASCII_ISALPHA(*p) || *p == '.')
1726 	    get_float = FALSE;
1727     }
1728     if (get_float)
1729     {
1730 	float_T	f;
1731 
1732 	*arg += string2float(*arg, &f);
1733 	if (evaluate)
1734 	{
1735 	    rettv->v_type = VAR_FLOAT;
1736 	    rettv->vval.v_float = f;
1737 	}
1738     }
1739     else
1740 #endif
1741     if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
1742     {
1743 	char_u  *bp;
1744 	blob_T  *blob = NULL;  // init for gcc
1745 
1746 	// Blob constant: 0z0123456789abcdef
1747 	if (evaluate)
1748 	    blob = blob_alloc();
1749 	for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
1750 	{
1751 	    if (!vim_isxdigit(bp[1]))
1752 	    {
1753 		if (blob != NULL)
1754 		{
1755 		    emsg(_("E973: Blob literal should have an even number of hex characters"));
1756 		    ga_clear(&blob->bv_ga);
1757 		    VIM_CLEAR(blob);
1758 		}
1759 		return FAIL;
1760 	    }
1761 	    if (blob != NULL)
1762 		ga_append(&blob->bv_ga,
1763 			     (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
1764 	    if (bp[2] == '.' && vim_isxdigit(bp[3]))
1765 		++bp;
1766 	}
1767 	if (blob != NULL)
1768 	    rettv_blob_set(rettv, blob);
1769 	*arg = bp;
1770     }
1771     else
1772     {
1773 	varnumber_T	n;
1774 
1775 	// decimal, hex or octal number
1776 	vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4
1777 		      ? STR2NR_NO_OCT + STR2NR_QUOTE
1778 		      : STR2NR_ALL, &n, NULL, 0, TRUE);
1779 	if (len == 0)
1780 	{
1781 	    semsg(_(e_invalid_expression_str), *arg);
1782 	    return FAIL;
1783 	}
1784 	*arg += len;
1785 	if (evaluate)
1786 	{
1787 	    rettv->v_type = VAR_NUMBER;
1788 	    rettv->vval.v_number = n;
1789 	}
1790     }
1791     return OK;
1792 }
1793 
1794 /*
1795  * Allocate a variable for a string constant.
1796  * Return OK or FAIL.
1797  */
1798     int
1799 eval_string(char_u **arg, typval_T *rettv, int evaluate)
1800 {
1801     char_u	*p;
1802     char_u	*end;
1803     int		extra = 0;
1804     int		len;
1805 
1806     // Find the end of the string, skipping backslashed characters.
1807     for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
1808     {
1809 	if (*p == '\\' && p[1] != NUL)
1810 	{
1811 	    ++p;
1812 	    // A "\<x>" form occupies at least 4 characters, and produces up
1813 	    // to 21 characters (3 * 6 for the char and 3 for a modifier):
1814 	    // reserve space for 18 extra.
1815 	    // Each byte in the char could be encoded as K_SPECIAL K_EXTRA x.
1816 	    if (*p == '<')
1817 		extra += 18;
1818 	}
1819     }
1820 
1821     if (*p != '"')
1822     {
1823 	semsg(_("E114: Missing quote: %s"), *arg);
1824 	return FAIL;
1825     }
1826 
1827     // If only parsing, set *arg and return here
1828     if (!evaluate)
1829     {
1830 	*arg = p + 1;
1831 	return OK;
1832     }
1833 
1834     // Copy the string into allocated memory, handling backslashed
1835     // characters.
1836     rettv->v_type = VAR_STRING;
1837     len = (int)(p - *arg + extra);
1838     rettv->vval.v_string = alloc(len);
1839     if (rettv->vval.v_string == NULL)
1840 	return FAIL;
1841     end = rettv->vval.v_string;
1842 
1843     for (p = *arg + 1; *p != NUL && *p != '"'; )
1844     {
1845 	if (*p == '\\')
1846 	{
1847 	    switch (*++p)
1848 	    {
1849 		case 'b': *end++ = BS; ++p; break;
1850 		case 'e': *end++ = ESC; ++p; break;
1851 		case 'f': *end++ = FF; ++p; break;
1852 		case 'n': *end++ = NL; ++p; break;
1853 		case 'r': *end++ = CAR; ++p; break;
1854 		case 't': *end++ = TAB; ++p; break;
1855 
1856 		case 'X': // hex: "\x1", "\x12"
1857 		case 'x':
1858 		case 'u': // Unicode: "\u0023"
1859 		case 'U':
1860 			  if (vim_isxdigit(p[1]))
1861 			  {
1862 			      int	n, nr;
1863 			      int	c = toupper(*p);
1864 
1865 			      if (c == 'X')
1866 				  n = 2;
1867 			      else if (*p == 'u')
1868 				  n = 4;
1869 			      else
1870 				  n = 8;
1871 			      nr = 0;
1872 			      while (--n >= 0 && vim_isxdigit(p[1]))
1873 			      {
1874 				  ++p;
1875 				  nr = (nr << 4) + hex2nr(*p);
1876 			      }
1877 			      ++p;
1878 			      // For "\u" store the number according to
1879 			      // 'encoding'.
1880 			      if (c != 'X')
1881 				  end += (*mb_char2bytes)(nr, end);
1882 			      else
1883 				  *end++ = nr;
1884 			  }
1885 			  break;
1886 
1887 			  // octal: "\1", "\12", "\123"
1888 		case '0':
1889 		case '1':
1890 		case '2':
1891 		case '3':
1892 		case '4':
1893 		case '5':
1894 		case '6':
1895 		case '7': *end = *p++ - '0';
1896 			  if (*p >= '0' && *p <= '7')
1897 			  {
1898 			      *end = (*end << 3) + *p++ - '0';
1899 			      if (*p >= '0' && *p <= '7')
1900 				  *end = (*end << 3) + *p++ - '0';
1901 			  }
1902 			  ++end;
1903 			  break;
1904 
1905 			  // Special key, e.g.: "\<C-W>"
1906 		case '<':
1907 			  {
1908 			      int flags = FSK_KEYCODE | FSK_IN_STRING;
1909 
1910 			      if (p[1] != '*')
1911 				  flags |= FSK_SIMPLIFY;
1912 			      extra = trans_special(&p, end, flags, NULL);
1913 			      if (extra != 0)
1914 			      {
1915 				  end += extra;
1916 				  if (end >= rettv->vval.v_string + len)
1917 				      iemsg("eval_string() used more space than allocated");
1918 				  break;
1919 			      }
1920 			  }
1921 			  // FALLTHROUGH
1922 
1923 		default:  MB_COPY_CHAR(p, end);
1924 			  break;
1925 	    }
1926 	}
1927 	else
1928 	    MB_COPY_CHAR(p, end);
1929     }
1930     *end = NUL;
1931     if (*p != NUL) // just in case
1932 	++p;
1933     *arg = p;
1934 
1935     return OK;
1936 }
1937 
1938 /*
1939  * Allocate a variable for a 'str''ing' constant.
1940  * Return OK or FAIL.
1941  */
1942     int
1943 eval_lit_string(char_u **arg, typval_T *rettv, int evaluate)
1944 {
1945     char_u	*p;
1946     char_u	*str;
1947     int		reduce = 0;
1948 
1949     // Find the end of the string, skipping ''.
1950     for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
1951     {
1952 	if (*p == '\'')
1953 	{
1954 	    if (p[1] != '\'')
1955 		break;
1956 	    ++reduce;
1957 	    ++p;
1958 	}
1959     }
1960 
1961     if (*p != '\'')
1962     {
1963 	semsg(_("E115: Missing quote: %s"), *arg);
1964 	return FAIL;
1965     }
1966 
1967     // If only parsing return after setting "*arg"
1968     if (!evaluate)
1969     {
1970 	*arg = p + 1;
1971 	return OK;
1972     }
1973 
1974     // Copy the string into allocated memory, handling '' to ' reduction.
1975     str = alloc((p - *arg) - reduce);
1976     if (str == NULL)
1977 	return FAIL;
1978     rettv->v_type = VAR_STRING;
1979     rettv->vval.v_string = str;
1980 
1981     for (p = *arg + 1; *p != NUL; )
1982     {
1983 	if (*p == '\'')
1984 	{
1985 	    if (p[1] != '\'')
1986 		break;
1987 	    ++p;
1988 	}
1989 	MB_COPY_CHAR(p, str);
1990     }
1991     *str = NUL;
1992     *arg = p + 1;
1993 
1994     return OK;
1995 }
1996 
1997 /*
1998  * Return a string with the string representation of a variable.
1999  * If the memory is allocated "tofree" is set to it, otherwise NULL.
2000  * "numbuf" is used for a number.
2001  * Puts quotes around strings, so that they can be parsed back by eval().
2002  * May return NULL.
2003  */
2004     char_u *
2005 tv2string(
2006     typval_T	*tv,
2007     char_u	**tofree,
2008     char_u	*numbuf,
2009     int		copyID)
2010 {
2011     return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
2012 }
2013 
2014 /*
2015  * Get the value of an environment variable.
2016  * "arg" is pointing to the '$'.  It is advanced to after the name.
2017  * If the environment variable was not set, silently assume it is empty.
2018  * Return FAIL if the name is invalid.
2019  */
2020     int
2021 eval_env_var(char_u **arg, typval_T *rettv, int evaluate)
2022 {
2023     char_u	*string = NULL;
2024     int		len;
2025     int		cc;
2026     char_u	*name;
2027     int		mustfree = FALSE;
2028 
2029     ++*arg;
2030     name = *arg;
2031     len = get_env_len(arg);
2032     if (evaluate)
2033     {
2034 	if (len == 0)
2035 	    return FAIL; // invalid empty name
2036 
2037 	cc = name[len];
2038 	name[len] = NUL;
2039 	// first try vim_getenv(), fast for normal environment vars
2040 	string = vim_getenv(name, &mustfree);
2041 	if (string != NULL && *string != NUL)
2042 	{
2043 	    if (!mustfree)
2044 		string = vim_strsave(string);
2045 	}
2046 	else
2047 	{
2048 	    if (mustfree)
2049 		vim_free(string);
2050 
2051 	    // next try expanding things like $VIM and ${HOME}
2052 	    string = expand_env_save(name - 1);
2053 	    if (string != NULL && *string == '$')
2054 		VIM_CLEAR(string);
2055 	}
2056 	name[len] = cc;
2057 
2058 	rettv->v_type = VAR_STRING;
2059 	rettv->vval.v_string = string;
2060     }
2061 
2062     return OK;
2063 }
2064 
2065 /*
2066  * Get the lnum from the first argument.
2067  * Also accepts ".", "$", etc., but that only works for the current buffer.
2068  * Returns -1 on error.
2069  */
2070     linenr_T
2071 tv_get_lnum(typval_T *argvars)
2072 {
2073     linenr_T	lnum = -1;
2074 
2075     if (argvars[0].v_type != VAR_STRING || !in_vim9script())
2076 	lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL);
2077     if (lnum <= 0 && argvars[0].v_type != VAR_NUMBER)
2078     {
2079 	int	fnum;
2080 	pos_T	*fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
2081 
2082 	// no valid number, try using arg like line()
2083 	if (fp != NULL)
2084 	    lnum = fp->lnum;
2085     }
2086     return lnum;
2087 }
2088 
2089 /*
2090  * Get the lnum from the first argument.
2091  * Also accepts "$", then "buf" is used.
2092  * Returns 0 on error.
2093  */
2094     linenr_T
2095 tv_get_lnum_buf(typval_T *argvars, buf_T *buf)
2096 {
2097     if (argvars[0].v_type == VAR_STRING
2098 	    && argvars[0].vval.v_string != NULL
2099 	    && argvars[0].vval.v_string[0] == '$'
2100 	    && buf != NULL)
2101 	return buf->b_ml.ml_line_count;
2102     return (linenr_T)tv_get_number_chk(&argvars[0], NULL);
2103 }
2104 
2105 /*
2106  * Get buffer by number or pattern.
2107  */
2108     buf_T *
2109 tv_get_buf(typval_T *tv, int curtab_only)
2110 {
2111     char_u	*name = tv->vval.v_string;
2112     buf_T	*buf;
2113 
2114     if (tv->v_type == VAR_NUMBER)
2115 	return buflist_findnr((int)tv->vval.v_number);
2116     if (tv->v_type != VAR_STRING)
2117 	return NULL;
2118     if (name == NULL || *name == NUL)
2119 	return curbuf;
2120     if (name[0] == '$' && name[1] == NUL)
2121 	return lastbuf;
2122 
2123     buf = buflist_find_by_name(name, curtab_only);
2124 
2125     // If not found, try expanding the name, like done for bufexists().
2126     if (buf == NULL)
2127 	buf = find_buffer(tv);
2128 
2129     return buf;
2130 }
2131 
2132 /*
2133  * Like tv_get_buf() but give an error message is the type is wrong.
2134  */
2135     buf_T *
2136 tv_get_buf_from_arg(typval_T *tv)
2137 {
2138     buf_T *buf;
2139 
2140     ++emsg_off;
2141     buf = tv_get_buf(tv, FALSE);
2142     --emsg_off;
2143     if (buf == NULL
2144 	    && tv->v_type != VAR_NUMBER
2145 	    && tv->v_type != VAR_STRING)
2146 	// issue errmsg for type error
2147 	(void)tv_get_number(tv);
2148     return buf;
2149 }
2150 
2151 #endif // FEAT_EVAL
2152