xref: /vim-8.2.3635/src/typval.c (revision 9faec4e3)
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 		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
104 clear_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
166 init_tv(typval_T *varp)
167 {
168     if (varp != NULL)
169 	CLEAR_POINTER(varp);
170 }
171 
172     static varnumber_T
173 tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
174 {
175     varnumber_T	n = 0L;
176 
177     switch (varp->v_type)
178     {
179 	case VAR_NUMBER:
180 	    if (in_vim9script() && want_bool && varp->vval.v_number != 0
181 						   && varp->vval.v_number != 1)
182 	    {
183 		semsg(_(e_using_number_as_bool_nr), varp->vval.v_number);
184 		break;
185 	    }
186 	    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:
197 	    if (in_vim9script())
198 	    {
199 		emsg_using_string_as(varp, !want_bool);
200 		break;
201 	    }
202 	    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:
214 	    if (!want_bool && in_vim9script())
215 	    {
216 		if (varp->v_type == VAR_BOOL)
217 		    emsg(_(e_using_bool_as_number));
218 		else
219 		    emsg(_("E611: Using a Special as a Number"));
220 		break;
221 	    }
222 	    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 
249 /*
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
258 tv_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
266 tv_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(),
273  * but in Vim9 script accepts Number (0 and 1) and Bool/Special.
274  */
275     varnumber_T
276 tv_get_bool(typval_T *varp)
277 {
278     return tv_get_bool_or_number_chk(varp, NULL, TRUE);
279 }
280 
281 /*
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
286 tv_get_bool_chk(typval_T *varp, int *denote)
287 {
288     return tv_get_bool_or_number_chk(varp, denote, TRUE);
289 }
290 
291 #ifdef FEAT_FLOAT
292     float_T
293 tv_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  * Give an error and return FAIL unless "tv" is a string.
345  */
346     int
347 check_for_string(typval_T *tv)
348 {
349     if (tv->v_type != VAR_STRING)
350     {
351 	emsg(_(e_stringreq));
352 	return FAIL;
353     }
354     return OK;
355 }
356 
357 /*
358  * Give an error and return FAIL unless "tv" is a non-empty string.
359  */
360     int
361 check_for_nonempty_string(typval_T *tv)
362 {
363     if (check_for_string(tv) == FAIL)
364 	return FAIL;
365     if (tv->vval.v_string == NULL || *tv->vval.v_string == NUL)
366     {
367 	emsg(_(e_non_empty_string_required));
368 	return FAIL;
369     }
370     return OK;
371 }
372 
373 /*
374  * Get the string value of a variable.
375  * If it is a Number variable, the number is converted into a string.
376  * tv_get_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
377  * tv_get_string_buf() uses a given buffer.
378  * If the String variable has never been set, return an empty string.
379  * Never returns NULL;
380  * tv_get_string_chk() and tv_get_string_buf_chk() are similar, but return
381  * NULL on error.
382  */
383     char_u *
384 tv_get_string(typval_T *varp)
385 {
386     static char_u   mybuf[NUMBUFLEN];
387 
388     return tv_get_string_buf(varp, mybuf);
389 }
390 
391 /*
392  * Like tv_get_string() but don't allow number to string conversion for Vim9.
393  */
394     char_u *
395 tv_get_string_strict(typval_T *varp)
396 {
397     static char_u   mybuf[NUMBUFLEN];
398     char_u	    *res =  tv_get_string_buf_chk_strict(
399 						 varp, mybuf, in_vim9script());
400 
401     return res != NULL ? res : (char_u *)"";
402 }
403 
404     char_u *
405 tv_get_string_buf(typval_T *varp, char_u *buf)
406 {
407     char_u	*res =  tv_get_string_buf_chk(varp, buf);
408 
409     return res != NULL ? res : (char_u *)"";
410 }
411 
412 /*
413  * Careful: This uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
414  */
415     char_u *
416 tv_get_string_chk(typval_T *varp)
417 {
418     static char_u   mybuf[NUMBUFLEN];
419 
420     return tv_get_string_buf_chk(varp, mybuf);
421 }
422 
423     char_u *
424 tv_get_string_buf_chk(typval_T *varp, char_u *buf)
425 {
426     return tv_get_string_buf_chk_strict(varp, buf, FALSE);
427 }
428 
429     char_u *
430 tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
431 {
432     switch (varp->v_type)
433     {
434 	case VAR_NUMBER:
435 	    if (strict)
436 	    {
437 		emsg(_(e_using_number_as_string));
438 		break;
439 	    }
440 	    vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
441 					    (varnumber_T)varp->vval.v_number);
442 	    return buf;
443 	case VAR_FUNC:
444 	case VAR_PARTIAL:
445 	    emsg(_("E729: using Funcref as a String"));
446 	    break;
447 	case VAR_LIST:
448 	    emsg(_("E730: using List as a String"));
449 	    break;
450 	case VAR_DICT:
451 	    emsg(_("E731: using Dictionary as a String"));
452 	    break;
453 	case VAR_FLOAT:
454 #ifdef FEAT_FLOAT
455 	    emsg(_(e_float_as_string));
456 	    break;
457 #endif
458 	case VAR_STRING:
459 	    if (varp->vval.v_string != NULL)
460 		return varp->vval.v_string;
461 	    return (char_u *)"";
462 	case VAR_BOOL:
463 	case VAR_SPECIAL:
464 	    STRCPY(buf, get_var_special_name(varp->vval.v_number));
465 	    return buf;
466         case VAR_BLOB:
467 	    emsg(_("E976: using Blob as a String"));
468 	    break;
469 	case VAR_JOB:
470 #ifdef FEAT_JOB_CHANNEL
471 	    {
472 		job_T *job = varp->vval.v_job;
473 		char  *status;
474 
475 		if (job == NULL)
476 		    return (char_u *)"no process";
477 		status = job->jv_status == JOB_FAILED ? "fail"
478 				: job->jv_status >= JOB_ENDED ? "dead"
479 				: "run";
480 # ifdef UNIX
481 		vim_snprintf((char *)buf, NUMBUFLEN,
482 			    "process %ld %s", (long)job->jv_pid, status);
483 # elif defined(MSWIN)
484 		vim_snprintf((char *)buf, NUMBUFLEN,
485 			    "process %ld %s",
486 			    (long)job->jv_proc_info.dwProcessId,
487 			    status);
488 # else
489 		// fall-back
490 		vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
491 # endif
492 		return buf;
493 	    }
494 #endif
495 	    break;
496 	case VAR_CHANNEL:
497 #ifdef FEAT_JOB_CHANNEL
498 	    {
499 		channel_T *channel = varp->vval.v_channel;
500 		char      *status = channel_status(channel, -1);
501 
502 		if (channel == NULL)
503 		    vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
504 		else
505 		    vim_snprintf((char *)buf, NUMBUFLEN,
506 				     "channel %d %s", channel->ch_id, status);
507 		return buf;
508 	    }
509 #endif
510 	    break;
511 	case VAR_UNKNOWN:
512 	case VAR_ANY:
513 	case VAR_VOID:
514 	    emsg(_(e_inval_string));
515 	    break;
516     }
517     return NULL;
518 }
519 
520 /*
521  * Turn a typeval into a string.  Similar to tv_get_string_buf() but uses
522  * string() on Dict, List, etc.
523  */
524     char_u *
525 tv_stringify(typval_T *varp, char_u *buf)
526 {
527     if (varp->v_type == VAR_LIST
528 	    || varp->v_type == VAR_DICT
529 	    || varp->v_type == VAR_BLOB
530 	    || varp->v_type == VAR_FUNC
531 	    || varp->v_type == VAR_PARTIAL
532 	    || varp->v_type == VAR_FLOAT)
533     {
534 	typval_T tmp;
535 
536 	f_string(varp, &tmp);
537 	tv_get_string_buf(&tmp, buf);
538 	clear_tv(varp);
539 	*varp = tmp;
540 	return tmp.vval.v_string;
541     }
542     return tv_get_string_buf(varp, buf);
543 }
544 
545 /*
546  * Return TRUE if typeval "tv" and its value are set to be locked (immutable).
547  * Also give an error message, using "name" or _("name") when use_gettext is
548  * TRUE.
549  */
550     int
551 tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
552 {
553     int	lock = 0;
554 
555     switch (tv->v_type)
556     {
557 	case VAR_BLOB:
558 	    if (tv->vval.v_blob != NULL)
559 		lock = tv->vval.v_blob->bv_lock;
560 	    break;
561 	case VAR_LIST:
562 	    if (tv->vval.v_list != NULL)
563 		lock = tv->vval.v_list->lv_lock;
564 	    break;
565 	case VAR_DICT:
566 	    if (tv->vval.v_dict != NULL)
567 		lock = tv->vval.v_dict->dv_lock;
568 	    break;
569 	default:
570 	    break;
571     }
572     return value_check_lock(tv->v_lock, name, use_gettext)
573 		   || (lock != 0 && value_check_lock(lock, name, use_gettext));
574 }
575 
576 /*
577  * Copy the values from typval_T "from" to typval_T "to".
578  * When needed allocates string or increases reference count.
579  * Does not make a copy of a list, blob or dict but copies the reference!
580  * It is OK for "from" and "to" to point to the same item.  This is used to
581  * make a copy later.
582  */
583     void
584 copy_tv(typval_T *from, typval_T *to)
585 {
586     to->v_type = from->v_type;
587     to->v_lock = 0;
588     switch (from->v_type)
589     {
590 	case VAR_NUMBER:
591 	case VAR_BOOL:
592 	case VAR_SPECIAL:
593 	    to->vval.v_number = from->vval.v_number;
594 	    break;
595 	case VAR_FLOAT:
596 #ifdef FEAT_FLOAT
597 	    to->vval.v_float = from->vval.v_float;
598 	    break;
599 #endif
600 	case VAR_JOB:
601 #ifdef FEAT_JOB_CHANNEL
602 	    to->vval.v_job = from->vval.v_job;
603 	    if (to->vval.v_job != NULL)
604 		++to->vval.v_job->jv_refcount;
605 	    break;
606 #endif
607 	case VAR_CHANNEL:
608 #ifdef FEAT_JOB_CHANNEL
609 	    to->vval.v_channel = from->vval.v_channel;
610 	    if (to->vval.v_channel != NULL)
611 		++to->vval.v_channel->ch_refcount;
612 	    break;
613 #endif
614 	case VAR_STRING:
615 	case VAR_FUNC:
616 	    if (from->vval.v_string == NULL)
617 		to->vval.v_string = NULL;
618 	    else
619 	    {
620 		to->vval.v_string = vim_strsave(from->vval.v_string);
621 		if (from->v_type == VAR_FUNC)
622 		    func_ref(to->vval.v_string);
623 	    }
624 	    break;
625 	case VAR_PARTIAL:
626 	    if (from->vval.v_partial == NULL)
627 		to->vval.v_partial = NULL;
628 	    else
629 	    {
630 		to->vval.v_partial = from->vval.v_partial;
631 		++to->vval.v_partial->pt_refcount;
632 	    }
633 	    break;
634 	case VAR_BLOB:
635 	    if (from->vval.v_blob == NULL)
636 		to->vval.v_blob = NULL;
637 	    else
638 	    {
639 		to->vval.v_blob = from->vval.v_blob;
640 		++to->vval.v_blob->bv_refcount;
641 	    }
642 	    break;
643 	case VAR_LIST:
644 	    if (from->vval.v_list == NULL)
645 		to->vval.v_list = NULL;
646 	    else
647 	    {
648 		to->vval.v_list = from->vval.v_list;
649 		++to->vval.v_list->lv_refcount;
650 	    }
651 	    break;
652 	case VAR_DICT:
653 	    if (from->vval.v_dict == NULL)
654 		to->vval.v_dict = NULL;
655 	    else
656 	    {
657 		to->vval.v_dict = from->vval.v_dict;
658 		++to->vval.v_dict->dv_refcount;
659 	    }
660 	    break;
661 	case VAR_UNKNOWN:
662 	case VAR_ANY:
663 	case VAR_VOID:
664 	    internal_error_no_abort("copy_tv(UNKNOWN)");
665 	    break;
666     }
667 }
668 
669 /*
670  * Compare "typ1" and "typ2".  Put the result in "typ1".
671  */
672     int
673 typval_compare(
674     typval_T	*typ1,   // first operand
675     typval_T	*typ2,   // second operand
676     exprtype_T	type,    // operator
677     int		ic)      // ignore case
678 {
679     int		i;
680     varnumber_T	n1, n2;
681     char_u	*s1, *s2;
682     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
683     int		type_is = type == EXPR_IS || type == EXPR_ISNOT;
684 
685     if (type_is && typ1->v_type != typ2->v_type)
686     {
687 	// For "is" a different type always means FALSE, for "notis"
688 	// it means TRUE.
689 	n1 = (type == EXPR_ISNOT);
690     }
691     else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
692     {
693 	if (type_is)
694 	{
695 	    n1 = (typ1->v_type == typ2->v_type
696 			    && typ1->vval.v_blob == typ2->vval.v_blob);
697 	    if (type == EXPR_ISNOT)
698 		n1 = !n1;
699 	}
700 	else if (typ1->v_type != typ2->v_type
701 		|| (type != EXPR_EQUAL && type != EXPR_NEQUAL))
702 	{
703 	    if (typ1->v_type != typ2->v_type)
704 		emsg(_("E977: Can only compare Blob with Blob"));
705 	    else
706 		emsg(_(e_invalblob));
707 	    clear_tv(typ1);
708 	    return FAIL;
709 	}
710 	else
711 	{
712 	    // Compare two Blobs for being equal or unequal.
713 	    n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
714 	    if (type == EXPR_NEQUAL)
715 		n1 = !n1;
716 	}
717     }
718     else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
719     {
720 	if (type_is)
721 	{
722 	    n1 = (typ1->v_type == typ2->v_type
723 			    && typ1->vval.v_list == typ2->vval.v_list);
724 	    if (type == EXPR_ISNOT)
725 		n1 = !n1;
726 	}
727 	else if (typ1->v_type != typ2->v_type
728 		|| (type != EXPR_EQUAL && type != EXPR_NEQUAL))
729 	{
730 	    if (typ1->v_type != typ2->v_type)
731 		emsg(_("E691: Can only compare List with List"));
732 	    else
733 		emsg(_("E692: Invalid operation for List"));
734 	    clear_tv(typ1);
735 	    return FAIL;
736 	}
737 	else
738 	{
739 	    // Compare two Lists for being equal or unequal.
740 	    n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
741 							    ic, FALSE);
742 	    if (type == EXPR_NEQUAL)
743 		n1 = !n1;
744 	}
745     }
746 
747     else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
748     {
749 	if (type_is)
750 	{
751 	    n1 = (typ1->v_type == typ2->v_type
752 			    && typ1->vval.v_dict == typ2->vval.v_dict);
753 	    if (type == EXPR_ISNOT)
754 		n1 = !n1;
755 	}
756 	else if (typ1->v_type != typ2->v_type
757 		|| (type != EXPR_EQUAL && type != EXPR_NEQUAL))
758 	{
759 	    if (typ1->v_type != typ2->v_type)
760 		emsg(_("E735: Can only compare Dictionary with Dictionary"));
761 	    else
762 		emsg(_("E736: Invalid operation for Dictionary"));
763 	    clear_tv(typ1);
764 	    return FAIL;
765 	}
766 	else
767 	{
768 	    // Compare two Dictionaries for being equal or unequal.
769 	    n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
770 							    ic, FALSE);
771 	    if (type == EXPR_NEQUAL)
772 		n1 = !n1;
773 	}
774     }
775 
776     else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
777 	|| typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
778     {
779 	if (type != EXPR_EQUAL && type != EXPR_NEQUAL
780 		&& type != EXPR_IS && type != EXPR_ISNOT)
781 	{
782 	    emsg(_("E694: Invalid operation for Funcrefs"));
783 	    clear_tv(typ1);
784 	    return FAIL;
785 	}
786 	if ((typ1->v_type == VAR_PARTIAL
787 					&& typ1->vval.v_partial == NULL)
788 		|| (typ2->v_type == VAR_PARTIAL
789 					&& typ2->vval.v_partial == NULL))
790 	    // When both partials are NULL, then they are equal.
791 	    // Otherwise they are not equal.
792 	    n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
793 	else if (type_is)
794 	{
795 	    if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
796 		// strings are considered the same if their value is
797 		// the same
798 		n1 = tv_equal(typ1, typ2, ic, FALSE);
799 	    else if (typ1->v_type == VAR_PARTIAL
800 					&& typ2->v_type == VAR_PARTIAL)
801 		n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
802 	    else
803 		n1 = FALSE;
804 	}
805 	else
806 	    n1 = tv_equal(typ1, typ2, ic, FALSE);
807 	if (type == EXPR_NEQUAL || type == EXPR_ISNOT)
808 	    n1 = !n1;
809     }
810 
811 #ifdef FEAT_FLOAT
812     // If one of the two variables is a float, compare as a float.
813     // When using "=~" or "!~", always compare as string.
814     else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
815 	    && type != EXPR_MATCH && type != EXPR_NOMATCH)
816     {
817 	float_T f1, f2;
818 
819 	f1 = tv_get_float(typ1);
820 	f2 = tv_get_float(typ2);
821 	n1 = FALSE;
822 	switch (type)
823 	{
824 	    case EXPR_IS:
825 	    case EXPR_EQUAL:    n1 = (f1 == f2); break;
826 	    case EXPR_ISNOT:
827 	    case EXPR_NEQUAL:   n1 = (f1 != f2); break;
828 	    case EXPR_GREATER:  n1 = (f1 > f2); break;
829 	    case EXPR_GEQUAL:   n1 = (f1 >= f2); break;
830 	    case EXPR_SMALLER:  n1 = (f1 < f2); break;
831 	    case EXPR_SEQUAL:   n1 = (f1 <= f2); break;
832 	    case EXPR_UNKNOWN:
833 	    case EXPR_MATCH:
834 	    default:  break;  // avoid gcc warning
835 	}
836     }
837 #endif
838 
839     // If one of the two variables is a number, compare as a number.
840     // When using "=~" or "!~", always compare as string.
841     else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
842 	    && type != EXPR_MATCH && type != EXPR_NOMATCH)
843     {
844 	n1 = tv_get_number(typ1);
845 	n2 = tv_get_number(typ2);
846 	switch (type)
847 	{
848 	    case EXPR_IS:
849 	    case EXPR_EQUAL:    n1 = (n1 == n2); break;
850 	    case EXPR_ISNOT:
851 	    case EXPR_NEQUAL:   n1 = (n1 != n2); break;
852 	    case EXPR_GREATER:  n1 = (n1 > n2); break;
853 	    case EXPR_GEQUAL:   n1 = (n1 >= n2); break;
854 	    case EXPR_SMALLER:  n1 = (n1 < n2); break;
855 	    case EXPR_SEQUAL:   n1 = (n1 <= n2); break;
856 	    case EXPR_UNKNOWN:
857 	    case EXPR_MATCH:
858 	    default:  break;  // avoid gcc warning
859 	}
860     }
861     else if (in_vim9script() && (typ1->v_type == VAR_BOOL
862 						 || typ2->v_type == VAR_BOOL))
863     {
864 	if (typ1->v_type != typ2->v_type)
865 	{
866 	    semsg(_(e_cannot_compare_str_with_str),
867 		       vartype_name(typ1->v_type), vartype_name(typ2->v_type));
868 	    clear_tv(typ1);
869 	    return FAIL;
870 	}
871 	n1 = typ1->vval.v_number;
872 	n2 = typ2->vval.v_number;
873 	switch (type)
874 	{
875 	    case EXPR_IS:
876 	    case EXPR_EQUAL:    n1 = (n1 == n2); break;
877 	    case EXPR_ISNOT:
878 	    case EXPR_NEQUAL:   n1 = (n1 != n2); break;
879 	    default:
880 		emsg(_(e_invalid_operation_for_bool));
881 		clear_tv(typ1);
882 		return FAIL;
883 	}
884     }
885     else
886     {
887 	s1 = tv_get_string_buf(typ1, buf1);
888 	s2 = tv_get_string_buf(typ2, buf2);
889 	if (type != EXPR_MATCH && type != EXPR_NOMATCH)
890 	    i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
891 	else
892 	    i = 0;
893 	n1 = FALSE;
894 	switch (type)
895 	{
896 	    case EXPR_IS:
897 	    case EXPR_EQUAL:    n1 = (i == 0); break;
898 	    case EXPR_ISNOT:
899 	    case EXPR_NEQUAL:   n1 = (i != 0); break;
900 	    case EXPR_GREATER:  n1 = (i > 0); break;
901 	    case EXPR_GEQUAL:   n1 = (i >= 0); break;
902 	    case EXPR_SMALLER:  n1 = (i < 0); break;
903 	    case EXPR_SEQUAL:   n1 = (i <= 0); break;
904 
905 	    case EXPR_MATCH:
906 	    case EXPR_NOMATCH:
907 		    n1 = pattern_match(s2, s1, ic);
908 		    if (type == EXPR_NOMATCH)
909 			n1 = !n1;
910 		    break;
911 
912 	    default:  break;  // avoid gcc warning
913 	}
914     }
915     clear_tv(typ1);
916     if (in_vim9script())
917     {
918 	typ1->v_type = VAR_BOOL;
919 	typ1->vval.v_number = n1 ? VVAL_TRUE : VVAL_FALSE;
920     }
921     else
922     {
923 	typ1->v_type = VAR_NUMBER;
924 	typ1->vval.v_number = n1;
925     }
926 
927     return OK;
928 }
929 
930 /*
931  * Convert any type to a string, never give an error.
932  * When "quotes" is TRUE add quotes to a string.
933  * Returns an allocated string.
934  */
935     char_u *
936 typval_tostring(typval_T *arg, int quotes)
937 {
938     char_u	*tofree;
939     char_u	numbuf[NUMBUFLEN];
940     char_u	*ret = NULL;
941 
942     if (arg == NULL)
943 	return vim_strsave((char_u *)"(does not exist)");
944     if (!quotes && arg->v_type == VAR_STRING)
945     {
946 	ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
947 							 : arg->vval.v_string);
948     }
949     else
950     {
951 	ret = tv2string(arg, &tofree, numbuf, 0);
952 	// Make a copy if we have a value but it's not in allocated memory.
953 	if (ret != NULL && tofree == NULL)
954 	    ret = vim_strsave(ret);
955     }
956     return ret;
957 }
958 
959 /*
960  * Return TRUE if typeval "tv" is locked: Either that value is locked itself
961  * or it refers to a List or Dictionary that is locked.
962  */
963     int
964 tv_islocked(typval_T *tv)
965 {
966     return (tv->v_lock & VAR_LOCKED)
967 	|| (tv->v_type == VAR_LIST
968 		&& tv->vval.v_list != NULL
969 		&& (tv->vval.v_list->lv_lock & VAR_LOCKED))
970 	|| (tv->v_type == VAR_DICT
971 		&& tv->vval.v_dict != NULL
972 		&& (tv->vval.v_dict->dv_lock & VAR_LOCKED));
973 }
974 
975     static int
976 func_equal(
977     typval_T *tv1,
978     typval_T *tv2,
979     int	     ic)	    // ignore case
980 {
981     char_u	*s1, *s2;
982     dict_T	*d1, *d2;
983     int		a1, a2;
984     int		i;
985 
986     // empty and NULL function name considered the same
987     s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
988 					   : partial_name(tv1->vval.v_partial);
989     if (s1 != NULL && *s1 == NUL)
990 	s1 = NULL;
991     s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
992 					   : partial_name(tv2->vval.v_partial);
993     if (s2 != NULL && *s2 == NUL)
994 	s2 = NULL;
995     if (s1 == NULL || s2 == NULL)
996     {
997 	if (s1 != s2)
998 	    return FALSE;
999     }
1000     else if (STRCMP(s1, s2) != 0)
1001 	return FALSE;
1002 
1003     // empty dict and NULL dict is different
1004     d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
1005     d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
1006     if (d1 == NULL || d2 == NULL)
1007     {
1008 	if (d1 != d2)
1009 	    return FALSE;
1010     }
1011     else if (!dict_equal(d1, d2, ic, TRUE))
1012 	return FALSE;
1013 
1014     // empty list and no list considered the same
1015     a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
1016     a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
1017     if (a1 != a2)
1018 	return FALSE;
1019     for (i = 0; i < a1; ++i)
1020 	if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
1021 		      tv2->vval.v_partial->pt_argv + i, ic, TRUE))
1022 	    return FALSE;
1023 
1024     return TRUE;
1025 }
1026 
1027 /*
1028  * Return TRUE if "tv1" and "tv2" have the same value.
1029  * Compares the items just like "==" would compare them, but strings and
1030  * numbers are different.  Floats and numbers are also different.
1031  */
1032     int
1033 tv_equal(
1034     typval_T *tv1,
1035     typval_T *tv2,
1036     int	     ic,	    // ignore case
1037     int	     recursive)	    // TRUE when used recursively
1038 {
1039     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1040     char_u	*s1, *s2;
1041     static int  recursive_cnt = 0;	    // catch recursive loops
1042     int		r;
1043     static int	tv_equal_recurse_limit;
1044 
1045     // Catch lists and dicts that have an endless loop by limiting
1046     // recursiveness to a limit.  We guess they are equal then.
1047     // A fixed limit has the problem of still taking an awful long time.
1048     // Reduce the limit every time running into it. That should work fine for
1049     // deeply linked structures that are not recursively linked and catch
1050     // recursiveness quickly.
1051     if (!recursive)
1052 	tv_equal_recurse_limit = 1000;
1053     if (recursive_cnt >= tv_equal_recurse_limit)
1054     {
1055 	--tv_equal_recurse_limit;
1056 	return TRUE;
1057     }
1058 
1059     // For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and
1060     // arguments.
1061     if ((tv1->v_type == VAR_FUNC
1062 		|| (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
1063 	    && (tv2->v_type == VAR_FUNC
1064 		|| (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
1065     {
1066 	++recursive_cnt;
1067 	r = func_equal(tv1, tv2, ic);
1068 	--recursive_cnt;
1069 	return r;
1070     }
1071 
1072     if (tv1->v_type != tv2->v_type
1073 	    && ((tv1->v_type != VAR_BOOL && tv1->v_type != VAR_SPECIAL)
1074 		|| (tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL)))
1075 	return FALSE;
1076 
1077     switch (tv1->v_type)
1078     {
1079 	case VAR_LIST:
1080 	    ++recursive_cnt;
1081 	    r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
1082 	    --recursive_cnt;
1083 	    return r;
1084 
1085 	case VAR_DICT:
1086 	    ++recursive_cnt;
1087 	    r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
1088 	    --recursive_cnt;
1089 	    return r;
1090 
1091 	case VAR_BLOB:
1092 	    return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
1093 
1094 	case VAR_NUMBER:
1095 	case VAR_BOOL:
1096 	case VAR_SPECIAL:
1097 	    return tv1->vval.v_number == tv2->vval.v_number;
1098 
1099 	case VAR_STRING:
1100 	    s1 = tv_get_string_buf(tv1, buf1);
1101 	    s2 = tv_get_string_buf(tv2, buf2);
1102 	    return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
1103 
1104 	case VAR_FLOAT:
1105 #ifdef FEAT_FLOAT
1106 	    return tv1->vval.v_float == tv2->vval.v_float;
1107 #endif
1108 	case VAR_JOB:
1109 #ifdef FEAT_JOB_CHANNEL
1110 	    return tv1->vval.v_job == tv2->vval.v_job;
1111 #endif
1112 	case VAR_CHANNEL:
1113 #ifdef FEAT_JOB_CHANNEL
1114 	    return tv1->vval.v_channel == tv2->vval.v_channel;
1115 #endif
1116 
1117 	case VAR_PARTIAL:
1118 	    return tv1->vval.v_partial == tv2->vval.v_partial;
1119 
1120 	case VAR_FUNC:
1121 	    return tv1->vval.v_string == tv2->vval.v_string;
1122 
1123 	case VAR_UNKNOWN:
1124 	case VAR_ANY:
1125 	case VAR_VOID:
1126 	    break;
1127     }
1128 
1129     // VAR_UNKNOWN can be the result of a invalid expression, let's say it
1130     // does not equal anything, not even itself.
1131     return FALSE;
1132 }
1133 
1134 /*
1135  * Get an option value.
1136  * "arg" points to the '&' or '+' before the option name.
1137  * "arg" is advanced to character after the option name.
1138  * Return OK or FAIL.
1139  */
1140     int
1141 eval_option(
1142     char_u	**arg,
1143     typval_T	*rettv,	// when NULL, only check if option exists
1144     int		evaluate)
1145 {
1146     char_u	*option_end;
1147     long	numval;
1148     char_u	*stringval;
1149     getoption_T	opt_type;
1150     int		c;
1151     int		working = (**arg == '+');    // has("+option")
1152     int		ret = OK;
1153     int		opt_flags;
1154 
1155     // Isolate the option name and find its value.
1156     option_end = find_option_end(arg, &opt_flags);
1157     if (option_end == NULL)
1158     {
1159 	if (rettv != NULL)
1160 	    semsg(_("E112: Option name missing: %s"), *arg);
1161 	return FAIL;
1162     }
1163 
1164     if (!evaluate)
1165     {
1166 	*arg = option_end;
1167 	return OK;
1168     }
1169 
1170     c = *option_end;
1171     *option_end = NUL;
1172     opt_type = get_option_value(*arg, &numval,
1173 			       rettv == NULL ? NULL : &stringval, opt_flags);
1174 
1175     if (opt_type == gov_unknown)
1176     {
1177 	if (rettv != NULL)
1178 	    semsg(_(e_unknown_option), *arg);
1179 	ret = FAIL;
1180     }
1181     else if (rettv != NULL)
1182     {
1183 	rettv->v_lock = 0;
1184 	if (opt_type == gov_hidden_string)
1185 	{
1186 	    rettv->v_type = VAR_STRING;
1187 	    rettv->vval.v_string = NULL;
1188 	}
1189 	else if (opt_type == gov_hidden_bool || opt_type == gov_hidden_number)
1190 	{
1191 	    rettv->v_type = in_vim9script() && opt_type == gov_hidden_bool
1192 						       ? VAR_BOOL : VAR_NUMBER;
1193 	    rettv->vval.v_number = 0;
1194 	}
1195 	else if (opt_type == gov_bool || opt_type == gov_number)
1196 	{
1197 	    if (in_vim9script() && opt_type == gov_bool)
1198 	    {
1199 		rettv->v_type = VAR_BOOL;
1200 		rettv->vval.v_number = numval ? VVAL_TRUE : VVAL_FALSE;
1201 	    }
1202 	    else
1203 	    {
1204 		rettv->v_type = VAR_NUMBER;
1205 		rettv->vval.v_number = numval;
1206 	    }
1207 	}
1208 	else				// string option
1209 	{
1210 	    rettv->v_type = VAR_STRING;
1211 	    rettv->vval.v_string = stringval;
1212 	}
1213     }
1214     else if (working && (opt_type == gov_hidden_bool
1215 			|| opt_type == gov_hidden_number
1216 			|| opt_type == gov_hidden_string))
1217 	ret = FAIL;
1218 
1219     *option_end = c;		    // put back for error messages
1220     *arg = option_end;
1221 
1222     return ret;
1223 }
1224 
1225 /*
1226  * Allocate a variable for a number constant.  Also deals with "0z" for blob.
1227  * Return OK or FAIL.
1228  */
1229     int
1230 eval_number(
1231 	char_u	    **arg,
1232 	typval_T    *rettv,
1233 	int	    evaluate,
1234 	int	    want_string UNUSED)
1235 {
1236     int		len;
1237 #ifdef FEAT_FLOAT
1238     char_u	*p;
1239     int		get_float = FALSE;
1240 
1241     // We accept a float when the format matches
1242     // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?".  This is very
1243     // strict to avoid backwards compatibility problems.
1244     // With script version 2 and later the leading digit can be
1245     // omitted.
1246     // Don't look for a float after the "." operator, so that
1247     // ":let vers = 1.2.3" doesn't fail.
1248     if (**arg == '.')
1249 	p = *arg;
1250     else
1251 	p = skipdigits(*arg + 1);
1252     if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
1253     {
1254 	get_float = TRUE;
1255 	p = skipdigits(p + 2);
1256 	if (*p == 'e' || *p == 'E')
1257 	{
1258 	    ++p;
1259 	    if (*p == '-' || *p == '+')
1260 		++p;
1261 	    if (!vim_isdigit(*p))
1262 		get_float = FALSE;
1263 	    else
1264 		p = skipdigits(p + 1);
1265 	}
1266 	if (ASCII_ISALPHA(*p) || *p == '.')
1267 	    get_float = FALSE;
1268     }
1269     if (get_float)
1270     {
1271 	float_T	f;
1272 
1273 	*arg += string2float(*arg, &f);
1274 	if (evaluate)
1275 	{
1276 	    rettv->v_type = VAR_FLOAT;
1277 	    rettv->vval.v_float = f;
1278 	}
1279     }
1280     else
1281 #endif
1282     if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
1283     {
1284 	char_u  *bp;
1285 	blob_T  *blob = NULL;  // init for gcc
1286 
1287 	// Blob constant: 0z0123456789abcdef
1288 	if (evaluate)
1289 	    blob = blob_alloc();
1290 	for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
1291 	{
1292 	    if (!vim_isxdigit(bp[1]))
1293 	    {
1294 		if (blob != NULL)
1295 		{
1296 		    emsg(_("E973: Blob literal should have an even number of hex characters"));
1297 		    ga_clear(&blob->bv_ga);
1298 		    VIM_CLEAR(blob);
1299 		}
1300 		return FAIL;
1301 	    }
1302 	    if (blob != NULL)
1303 		ga_append(&blob->bv_ga,
1304 			     (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
1305 	    if (bp[2] == '.' && vim_isxdigit(bp[3]))
1306 		++bp;
1307 	}
1308 	if (blob != NULL)
1309 	    rettv_blob_set(rettv, blob);
1310 	*arg = bp;
1311     }
1312     else
1313     {
1314 	varnumber_T	n;
1315 
1316 	// decimal, hex or octal number
1317 	vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4
1318 		      ? STR2NR_NO_OCT + STR2NR_QUOTE
1319 		      : STR2NR_ALL, &n, NULL, 0, TRUE);
1320 	if (len == 0)
1321 	{
1322 	    semsg(_(e_invexpr2), *arg);
1323 	    return FAIL;
1324 	}
1325 	*arg += len;
1326 	if (evaluate)
1327 	{
1328 	    rettv->v_type = VAR_NUMBER;
1329 	    rettv->vval.v_number = n;
1330 	}
1331     }
1332     return OK;
1333 }
1334 
1335 /*
1336  * Allocate a variable for a string constant.
1337  * Return OK or FAIL.
1338  */
1339     int
1340 eval_string(char_u **arg, typval_T *rettv, int evaluate)
1341 {
1342     char_u	*p;
1343     char_u	*end;
1344     int		extra = 0;
1345     int		len;
1346 
1347     // Find the end of the string, skipping backslashed characters.
1348     for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
1349     {
1350 	if (*p == '\\' && p[1] != NUL)
1351 	{
1352 	    ++p;
1353 	    // A "\<x>" form occupies at least 4 characters, and produces up
1354 	    // to 21 characters (3 * 6 for the char and 3 for a modifier):
1355 	    // reserve space for 18 extra.
1356 	    // Each byte in the char could be encoded as K_SPECIAL K_EXTRA x.
1357 	    if (*p == '<')
1358 		extra += 18;
1359 	}
1360     }
1361 
1362     if (*p != '"')
1363     {
1364 	semsg(_("E114: Missing quote: %s"), *arg);
1365 	return FAIL;
1366     }
1367 
1368     // If only parsing, set *arg and return here
1369     if (!evaluate)
1370     {
1371 	*arg = p + 1;
1372 	return OK;
1373     }
1374 
1375     // Copy the string into allocated memory, handling backslashed
1376     // characters.
1377     rettv->v_type = VAR_STRING;
1378     len = (int)(p - *arg + extra);
1379     rettv->vval.v_string = alloc(len);
1380     if (rettv->vval.v_string == NULL)
1381 	return FAIL;
1382     end = rettv->vval.v_string;
1383 
1384     for (p = *arg + 1; *p != NUL && *p != '"'; )
1385     {
1386 	if (*p == '\\')
1387 	{
1388 	    switch (*++p)
1389 	    {
1390 		case 'b': *end++ = BS; ++p; break;
1391 		case 'e': *end++ = ESC; ++p; break;
1392 		case 'f': *end++ = FF; ++p; break;
1393 		case 'n': *end++ = NL; ++p; break;
1394 		case 'r': *end++ = CAR; ++p; break;
1395 		case 't': *end++ = TAB; ++p; break;
1396 
1397 		case 'X': // hex: "\x1", "\x12"
1398 		case 'x':
1399 		case 'u': // Unicode: "\u0023"
1400 		case 'U':
1401 			  if (vim_isxdigit(p[1]))
1402 			  {
1403 			      int	n, nr;
1404 			      int	c = toupper(*p);
1405 
1406 			      if (c == 'X')
1407 				  n = 2;
1408 			      else if (*p == 'u')
1409 				  n = 4;
1410 			      else
1411 				  n = 8;
1412 			      nr = 0;
1413 			      while (--n >= 0 && vim_isxdigit(p[1]))
1414 			      {
1415 				  ++p;
1416 				  nr = (nr << 4) + hex2nr(*p);
1417 			      }
1418 			      ++p;
1419 			      // For "\u" store the number according to
1420 			      // 'encoding'.
1421 			      if (c != 'X')
1422 				  end += (*mb_char2bytes)(nr, end);
1423 			      else
1424 				  *end++ = nr;
1425 			  }
1426 			  break;
1427 
1428 			  // octal: "\1", "\12", "\123"
1429 		case '0':
1430 		case '1':
1431 		case '2':
1432 		case '3':
1433 		case '4':
1434 		case '5':
1435 		case '6':
1436 		case '7': *end = *p++ - '0';
1437 			  if (*p >= '0' && *p <= '7')
1438 			  {
1439 			      *end = (*end << 3) + *p++ - '0';
1440 			      if (*p >= '0' && *p <= '7')
1441 				  *end = (*end << 3) + *p++ - '0';
1442 			  }
1443 			  ++end;
1444 			  break;
1445 
1446 			  // Special key, e.g.: "\<C-W>"
1447 		case '<':
1448 			  {
1449 			      int flags = FSK_KEYCODE | FSK_IN_STRING;
1450 
1451 			      if (p[1] != '*')
1452 				  flags |= FSK_SIMPLIFY;
1453 			      extra = trans_special(&p, end, flags, NULL);
1454 			      if (extra != 0)
1455 			      {
1456 				  end += extra;
1457 				  if (end >= rettv->vval.v_string + len)
1458 				      iemsg("eval_string() used more space than allocated");
1459 				  break;
1460 			      }
1461 			  }
1462 			  // FALLTHROUGH
1463 
1464 		default:  MB_COPY_CHAR(p, end);
1465 			  break;
1466 	    }
1467 	}
1468 	else
1469 	    MB_COPY_CHAR(p, end);
1470     }
1471     *end = NUL;
1472     if (*p != NUL) // just in case
1473 	++p;
1474     *arg = p;
1475 
1476     return OK;
1477 }
1478 
1479 /*
1480  * Allocate a variable for a 'str''ing' constant.
1481  * Return OK or FAIL.
1482  */
1483     int
1484 eval_lit_string(char_u **arg, typval_T *rettv, int evaluate)
1485 {
1486     char_u	*p;
1487     char_u	*str;
1488     int		reduce = 0;
1489 
1490     // Find the end of the string, skipping ''.
1491     for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
1492     {
1493 	if (*p == '\'')
1494 	{
1495 	    if (p[1] != '\'')
1496 		break;
1497 	    ++reduce;
1498 	    ++p;
1499 	}
1500     }
1501 
1502     if (*p != '\'')
1503     {
1504 	semsg(_("E115: Missing quote: %s"), *arg);
1505 	return FAIL;
1506     }
1507 
1508     // If only parsing return after setting "*arg"
1509     if (!evaluate)
1510     {
1511 	*arg = p + 1;
1512 	return OK;
1513     }
1514 
1515     // Copy the string into allocated memory, handling '' to ' reduction.
1516     str = alloc((p - *arg) - reduce);
1517     if (str == NULL)
1518 	return FAIL;
1519     rettv->v_type = VAR_STRING;
1520     rettv->vval.v_string = str;
1521 
1522     for (p = *arg + 1; *p != NUL; )
1523     {
1524 	if (*p == '\'')
1525 	{
1526 	    if (p[1] != '\'')
1527 		break;
1528 	    ++p;
1529 	}
1530 	MB_COPY_CHAR(p, str);
1531     }
1532     *str = NUL;
1533     *arg = p + 1;
1534 
1535     return OK;
1536 }
1537 
1538 /*
1539  * Return a string with the string representation of a variable.
1540  * If the memory is allocated "tofree" is set to it, otherwise NULL.
1541  * "numbuf" is used for a number.
1542  * Puts quotes around strings, so that they can be parsed back by eval().
1543  * May return NULL.
1544  */
1545     char_u *
1546 tv2string(
1547     typval_T	*tv,
1548     char_u	**tofree,
1549     char_u	*numbuf,
1550     int		copyID)
1551 {
1552     return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
1553 }
1554 
1555 /*
1556  * Get the value of an environment variable.
1557  * "arg" is pointing to the '$'.  It is advanced to after the name.
1558  * If the environment variable was not set, silently assume it is empty.
1559  * Return FAIL if the name is invalid.
1560  */
1561     int
1562 eval_env_var(char_u **arg, typval_T *rettv, int evaluate)
1563 {
1564     char_u	*string = NULL;
1565     int		len;
1566     int		cc;
1567     char_u	*name;
1568     int		mustfree = FALSE;
1569 
1570     ++*arg;
1571     name = *arg;
1572     len = get_env_len(arg);
1573     if (evaluate)
1574     {
1575 	if (len == 0)
1576 	    return FAIL; // invalid empty name
1577 
1578 	cc = name[len];
1579 	name[len] = NUL;
1580 	// first try vim_getenv(), fast for normal environment vars
1581 	string = vim_getenv(name, &mustfree);
1582 	if (string != NULL && *string != NUL)
1583 	{
1584 	    if (!mustfree)
1585 		string = vim_strsave(string);
1586 	}
1587 	else
1588 	{
1589 	    if (mustfree)
1590 		vim_free(string);
1591 
1592 	    // next try expanding things like $VIM and ${HOME}
1593 	    string = expand_env_save(name - 1);
1594 	    if (string != NULL && *string == '$')
1595 		VIM_CLEAR(string);
1596 	}
1597 	name[len] = cc;
1598 
1599 	rettv->v_type = VAR_STRING;
1600 	rettv->vval.v_string = string;
1601     }
1602 
1603     return OK;
1604 }
1605 
1606 /*
1607  * Get the lnum from the first argument.
1608  * Also accepts ".", "$", etc., but that only works for the current buffer.
1609  * Returns -1 on error.
1610  */
1611     linenr_T
1612 tv_get_lnum(typval_T *argvars)
1613 {
1614     linenr_T	lnum = -1;
1615 
1616     if (argvars[0].v_type != VAR_STRING || !in_vim9script())
1617 	lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL);
1618     if (lnum <= 0)  // no valid number, try using arg like line()
1619     {
1620 	int	fnum;
1621 	pos_T	*fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
1622 
1623 	if (fp != NULL)
1624 	    lnum = fp->lnum;
1625     }
1626     return lnum;
1627 }
1628 
1629 /*
1630  * Get the lnum from the first argument.
1631  * Also accepts "$", then "buf" is used.
1632  * Returns 0 on error.
1633  */
1634     linenr_T
1635 tv_get_lnum_buf(typval_T *argvars, buf_T *buf)
1636 {
1637     if (argvars[0].v_type == VAR_STRING
1638 	    && argvars[0].vval.v_string != NULL
1639 	    && argvars[0].vval.v_string[0] == '$'
1640 	    && buf != NULL)
1641 	return buf->b_ml.ml_line_count;
1642     return (linenr_T)tv_get_number_chk(&argvars[0], NULL);
1643 }
1644 
1645 /*
1646  * Get buffer by number or pattern.
1647  */
1648     buf_T *
1649 tv_get_buf(typval_T *tv, int curtab_only)
1650 {
1651     char_u	*name = tv->vval.v_string;
1652     buf_T	*buf;
1653 
1654     if (tv->v_type == VAR_NUMBER)
1655 	return buflist_findnr((int)tv->vval.v_number);
1656     if (tv->v_type != VAR_STRING)
1657 	return NULL;
1658     if (name == NULL || *name == NUL)
1659 	return curbuf;
1660     if (name[0] == '$' && name[1] == NUL)
1661 	return lastbuf;
1662 
1663     buf = buflist_find_by_name(name, curtab_only);
1664 
1665     // If not found, try expanding the name, like done for bufexists().
1666     if (buf == NULL)
1667 	buf = find_buffer(tv);
1668 
1669     return buf;
1670 }
1671 
1672 /*
1673  * Like tv_get_buf() but give an error message is the type is wrong.
1674  */
1675     buf_T *
1676 tv_get_buf_from_arg(typval_T *tv)
1677 {
1678     buf_T *buf;
1679 
1680     ++emsg_off;
1681     buf = tv_get_buf(tv, FALSE);
1682     --emsg_off;
1683     if (buf == NULL
1684 	    && tv->v_type != VAR_NUMBER
1685 	    && tv->v_type != VAR_STRING)
1686 	// issue errmsg for type error
1687 	(void)tv_get_number(tv);
1688     return buf;
1689 }
1690 
1691 #endif // FEAT_EVAL
1692