blob: 4bde94e19221f9e9a816fa841cf3b26358655450 [file] [log] [blame]
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001/* vi:set ts=8 sts=4 sw=4 noet:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * typval.c: functions that deal with a typval
12 */
13
14#include "vim.h"
15
16#if defined(FEAT_EVAL) || defined(PROTO)
17
18/*
19 * Allocate memory for a variable type-value, and make it empty (0 or NULL
20 * value).
21 */
22 typval_T *
23alloc_tv(void)
24{
25 return ALLOC_CLEAR_ONE(typval_T);
26}
27
28/*
29 * Allocate memory for a variable type-value, and assign a string to it.
30 * The string "s" must have been allocated, it is consumed.
31 * Return NULL for out of memory, the variable otherwise.
32 */
33 typval_T *
34alloc_string_tv(char_u *s)
35{
36 typval_T *rettv;
37
38 rettv = alloc_tv();
39 if (rettv != NULL)
40 {
41 rettv->v_type = VAR_STRING;
42 rettv->vval.v_string = s;
43 }
44 else
45 vim_free(s);
46 return rettv;
47}
48
49/*
50 * Free the memory for a variable type-value.
51 */
52 void
53free_tv(typval_T *varp)
54{
55 if (varp != NULL)
56 {
57 switch (varp->v_type)
58 {
59 case VAR_FUNC:
60 func_unref(varp->vval.v_string);
61 // FALLTHROUGH
62 case VAR_STRING:
63 vim_free(varp->vval.v_string);
64 break;
65 case VAR_PARTIAL:
66 partial_unref(varp->vval.v_partial);
67 break;
68 case VAR_BLOB:
69 blob_unref(varp->vval.v_blob);
70 break;
71 case VAR_LIST:
72 list_unref(varp->vval.v_list);
73 break;
74 case VAR_DICT:
75 dict_unref(varp->vval.v_dict);
76 break;
77 case VAR_JOB:
78#ifdef FEAT_JOB_CHANNEL
79 job_unref(varp->vval.v_job);
80 break;
81#endif
82 case VAR_CHANNEL:
83#ifdef FEAT_JOB_CHANNEL
84 channel_unref(varp->vval.v_channel);
85 break;
86#endif
87 case VAR_NUMBER:
88 case VAR_FLOAT:
89 case VAR_ANY:
90 case VAR_UNKNOWN:
91 case VAR_VOID:
92 case VAR_BOOL:
93 case VAR_SPECIAL:
Bram Moolenaarf18332f2021-05-07 17:55:55 +020094 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +020095 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
105clear_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 case VAR_UNKNOWN:
155 case VAR_ANY:
156 case VAR_VOID:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200157 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200158 break;
159 }
160 varp->v_lock = 0;
161 }
162}
163
164/*
165 * Set the value of a variable to NULL without freeing items.
166 */
167 void
168init_tv(typval_T *varp)
169{
170 if (varp != NULL)
171 CLEAR_POINTER(varp);
172}
173
Bram Moolenaar36967b32020-08-17 21:41:02 +0200174 static varnumber_T
175tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200176{
177 varnumber_T n = 0L;
178
179 switch (varp->v_type)
180 {
181 case VAR_NUMBER:
Bram Moolenaarbade44e2020-09-26 22:39:24 +0200182 if (in_vim9script() && want_bool && varp->vval.v_number != 0
Bram Moolenaard70840e2020-08-22 15:06:35 +0200183 && varp->vval.v_number != 1)
184 {
185 semsg(_(e_using_number_as_bool_nr), varp->vval.v_number);
186 break;
187 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200188 return varp->vval.v_number;
189 case VAR_FLOAT:
190#ifdef FEAT_FLOAT
191 emsg(_("E805: Using a Float as a Number"));
192 break;
193#endif
194 case VAR_FUNC:
195 case VAR_PARTIAL:
196 emsg(_("E703: Using a Funcref as a Number"));
197 break;
198 case VAR_STRING:
Bram Moolenaar56acb092020-08-16 14:48:19 +0200199 if (in_vim9script())
200 {
Bram Moolenaarea2d4072020-11-12 12:08:51 +0100201 emsg_using_string_as(varp, !want_bool);
Bram Moolenaar56acb092020-08-16 14:48:19 +0200202 break;
203 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200204 if (varp->vval.v_string != NULL)
205 vim_str2nr(varp->vval.v_string, NULL, NULL,
206 STR2NR_ALL, &n, NULL, 0, FALSE);
207 return n;
208 case VAR_LIST:
209 emsg(_("E745: Using a List as a Number"));
210 break;
211 case VAR_DICT:
212 emsg(_("E728: Using a Dictionary as a Number"));
213 break;
214 case VAR_BOOL:
215 case VAR_SPECIAL:
Bram Moolenaar36967b32020-08-17 21:41:02 +0200216 if (!want_bool && in_vim9script())
Bram Moolenaar56acb092020-08-16 14:48:19 +0200217 {
Bram Moolenaard92cc132020-11-18 17:17:15 +0100218 if (varp->v_type == VAR_BOOL)
219 emsg(_(e_using_bool_as_number));
220 else
221 emsg(_("E611: Using a Special as a Number"));
Bram Moolenaar56acb092020-08-16 14:48:19 +0200222 break;
223 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200224 return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
225 case VAR_JOB:
226#ifdef FEAT_JOB_CHANNEL
227 emsg(_("E910: Using a Job as a Number"));
228 break;
229#endif
230 case VAR_CHANNEL:
231#ifdef FEAT_JOB_CHANNEL
232 emsg(_("E913: Using a Channel as a Number"));
233 break;
234#endif
235 case VAR_BLOB:
236 emsg(_("E974: Using a Blob as a Number"));
237 break;
238 case VAR_UNKNOWN:
239 case VAR_ANY:
240 case VAR_VOID:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200241 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200242 internal_error_no_abort("tv_get_number(UNKNOWN)");
243 break;
244 }
245 if (denote == NULL) // useful for values that must be unsigned
246 n = -1;
247 else
248 *denote = TRUE;
249 return n;
250}
251
Bram Moolenaar36967b32020-08-17 21:41:02 +0200252/*
253 * Get the number value of a variable.
254 * If it is a String variable, uses vim_str2nr().
255 * For incompatible types, return 0.
256 * tv_get_number_chk() is similar to tv_get_number(), but informs the
257 * caller of incompatible types: it sets *denote to TRUE if "denote"
258 * is not NULL or returns -1 otherwise.
259 */
260 varnumber_T
261tv_get_number(typval_T *varp)
262{
263 int error = FALSE;
264
265 return tv_get_number_chk(varp, &error); // return 0L on error
266}
267
268 varnumber_T
269tv_get_number_chk(typval_T *varp, int *denote)
270{
271 return tv_get_bool_or_number_chk(varp, denote, FALSE);
272}
273
274/*
275 * Get the boolean value of "varp". This is like tv_get_number_chk(),
Bram Moolenaard70840e2020-08-22 15:06:35 +0200276 * but in Vim9 script accepts Number (0 and 1) and Bool/Special.
Bram Moolenaar36967b32020-08-17 21:41:02 +0200277 */
278 varnumber_T
279tv_get_bool(typval_T *varp)
280{
281 return tv_get_bool_or_number_chk(varp, NULL, TRUE);
Bram Moolenaar36967b32020-08-17 21:41:02 +0200282}
283
Bram Moolenaare15eebd2020-08-18 19:11:38 +0200284/*
285 * Get the boolean value of "varp". This is like tv_get_number_chk(),
286 * but in Vim9 script accepts Number and Bool.
287 */
288 varnumber_T
289tv_get_bool_chk(typval_T *varp, int *denote)
290{
291 return tv_get_bool_or_number_chk(varp, denote, TRUE);
Bram Moolenaare15eebd2020-08-18 19:11:38 +0200292}
293
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200294#ifdef FEAT_FLOAT
295 float_T
296tv_get_float(typval_T *varp)
297{
298 switch (varp->v_type)
299 {
300 case VAR_NUMBER:
301 return (float_T)(varp->vval.v_number);
302 case VAR_FLOAT:
303 return varp->vval.v_float;
304 case VAR_FUNC:
305 case VAR_PARTIAL:
306 emsg(_("E891: Using a Funcref as a Float"));
307 break;
308 case VAR_STRING:
309 emsg(_("E892: Using a String as a Float"));
310 break;
311 case VAR_LIST:
312 emsg(_("E893: Using a List as a Float"));
313 break;
314 case VAR_DICT:
315 emsg(_("E894: Using a Dictionary as a Float"));
316 break;
317 case VAR_BOOL:
318 emsg(_("E362: Using a boolean value as a Float"));
319 break;
320 case VAR_SPECIAL:
321 emsg(_("E907: Using a special value as a Float"));
322 break;
323 case VAR_JOB:
324# ifdef FEAT_JOB_CHANNEL
325 emsg(_("E911: Using a Job as a Float"));
326 break;
327# endif
328 case VAR_CHANNEL:
329# ifdef FEAT_JOB_CHANNEL
330 emsg(_("E914: Using a Channel as a Float"));
331 break;
332# endif
333 case VAR_BLOB:
334 emsg(_("E975: Using a Blob as a Float"));
335 break;
336 case VAR_UNKNOWN:
337 case VAR_ANY:
338 case VAR_VOID:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200339 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200340 internal_error_no_abort("tv_get_float(UNKNOWN)");
341 break;
342 }
343 return 0;
344}
345#endif
346
347/*
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100348 * Give an error and return FAIL unless "tv" is a string.
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100349 */
350 int
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100351check_for_string_arg(typval_T *args, int idx)
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100352{
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100353 if (args[idx].v_type != VAR_STRING)
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100354 {
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100355 if (idx >= 0)
356 semsg(_(e_string_required_for_argument_nr), idx + 1);
Bram Moolenaarf28f2ac2021-03-22 22:21:26 +0100357 else
358 emsg(_(e_stringreq));
Bram Moolenaar7bb4e742020-12-09 12:41:50 +0100359 return FAIL;
360 }
361 return OK;
362}
363
364/*
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100365 * Give an error and return FAIL unless "args[idx]" is a non-empty string.
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100366 */
367 int
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100368check_for_nonempty_string_arg(typval_T *args, int idx)
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100369{
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100370 if (check_for_string_arg(args, idx) == FAIL)
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100371 return FAIL;
Bram Moolenaar32105ae2021-03-27 18:59:25 +0100372 if (args[idx].vval.v_string == NULL || *args[idx].vval.v_string == NUL)
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100373 {
Bram Moolenaare8e30782021-04-10 21:46:05 +0200374 semsg(_(e_non_empty_string_required_for_argument_nr), idx + 1);
Bram Moolenaar2a9d5d32020-12-12 18:58:40 +0100375 return FAIL;
376 }
377 return OK;
378}
379
380/*
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200381 * Get the string value of a variable.
382 * If it is a Number variable, the number is converted into a string.
383 * tv_get_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
384 * tv_get_string_buf() uses a given buffer.
385 * If the String variable has never been set, return an empty string.
386 * Never returns NULL;
387 * tv_get_string_chk() and tv_get_string_buf_chk() are similar, but return
388 * NULL on error.
389 */
390 char_u *
391tv_get_string(typval_T *varp)
392{
393 static char_u mybuf[NUMBUFLEN];
394
395 return tv_get_string_buf(varp, mybuf);
396}
397
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100398/*
399 * Like tv_get_string() but don't allow number to string conversion for Vim9.
400 */
401 char_u *
402tv_get_string_strict(typval_T *varp)
403{
404 static char_u mybuf[NUMBUFLEN];
405 char_u *res = tv_get_string_buf_chk_strict(
406 varp, mybuf, in_vim9script());
407
408 return res != NULL ? res : (char_u *)"";
409}
410
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200411 char_u *
412tv_get_string_buf(typval_T *varp, char_u *buf)
413{
414 char_u *res = tv_get_string_buf_chk(varp, buf);
415
416 return res != NULL ? res : (char_u *)"";
417}
418
419/*
420 * Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
421 */
422 char_u *
423tv_get_string_chk(typval_T *varp)
424{
425 static char_u mybuf[NUMBUFLEN];
426
427 return tv_get_string_buf_chk(varp, mybuf);
428}
429
430 char_u *
431tv_get_string_buf_chk(typval_T *varp, char_u *buf)
432{
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100433 return tv_get_string_buf_chk_strict(varp, buf, FALSE);
434}
435
436 char_u *
437tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
438{
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200439 switch (varp->v_type)
440 {
441 case VAR_NUMBER:
Bram Moolenaarf2b26bc2021-01-30 23:05:11 +0100442 if (strict)
443 {
444 emsg(_(e_using_number_as_string));
445 break;
446 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200447 vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
448 (varnumber_T)varp->vval.v_number);
449 return buf;
450 case VAR_FUNC:
451 case VAR_PARTIAL:
452 emsg(_("E729: using Funcref as a String"));
453 break;
454 case VAR_LIST:
455 emsg(_("E730: using List as a String"));
456 break;
457 case VAR_DICT:
458 emsg(_("E731: using Dictionary as a String"));
459 break;
460 case VAR_FLOAT:
461#ifdef FEAT_FLOAT
462 emsg(_(e_float_as_string));
463 break;
464#endif
465 case VAR_STRING:
466 if (varp->vval.v_string != NULL)
467 return varp->vval.v_string;
468 return (char_u *)"";
469 case VAR_BOOL:
470 case VAR_SPECIAL:
471 STRCPY(buf, get_var_special_name(varp->vval.v_number));
472 return buf;
473 case VAR_BLOB:
474 emsg(_("E976: using Blob as a String"));
475 break;
476 case VAR_JOB:
477#ifdef FEAT_JOB_CHANNEL
478 {
479 job_T *job = varp->vval.v_job;
480 char *status;
481
482 if (job == NULL)
483 return (char_u *)"no process";
484 status = job->jv_status == JOB_FAILED ? "fail"
485 : job->jv_status >= JOB_ENDED ? "dead"
486 : "run";
487# ifdef UNIX
488 vim_snprintf((char *)buf, NUMBUFLEN,
489 "process %ld %s", (long)job->jv_pid, status);
490# elif defined(MSWIN)
491 vim_snprintf((char *)buf, NUMBUFLEN,
492 "process %ld %s",
493 (long)job->jv_proc_info.dwProcessId,
494 status);
495# else
496 // fall-back
497 vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
498# endif
499 return buf;
500 }
501#endif
502 break;
503 case VAR_CHANNEL:
504#ifdef FEAT_JOB_CHANNEL
505 {
506 channel_T *channel = varp->vval.v_channel;
507 char *status = channel_status(channel, -1);
508
509 if (channel == NULL)
510 vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
511 else
512 vim_snprintf((char *)buf, NUMBUFLEN,
513 "channel %d %s", channel->ch_id, status);
514 return buf;
515 }
516#endif
517 break;
518 case VAR_UNKNOWN:
519 case VAR_ANY:
520 case VAR_VOID:
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200521 case VAR_INSTR:
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200522 emsg(_(e_inval_string));
523 break;
524 }
525 return NULL;
526}
527
528/*
529 * Turn a typeval into a string. Similar to tv_get_string_buf() but uses
530 * string() on Dict, List, etc.
531 */
532 char_u *
533tv_stringify(typval_T *varp, char_u *buf)
534{
535 if (varp->v_type == VAR_LIST
536 || varp->v_type == VAR_DICT
537 || varp->v_type == VAR_BLOB
538 || varp->v_type == VAR_FUNC
539 || varp->v_type == VAR_PARTIAL
540 || varp->v_type == VAR_FLOAT)
541 {
542 typval_T tmp;
543
544 f_string(varp, &tmp);
545 tv_get_string_buf(&tmp, buf);
546 clear_tv(varp);
547 *varp = tmp;
548 return tmp.vval.v_string;
549 }
550 return tv_get_string_buf(varp, buf);
551}
552
553/*
554 * Return TRUE if typeval "tv" and its value are set to be locked (immutable).
555 * Also give an error message, using "name" or _("name") when use_gettext is
556 * TRUE.
557 */
558 int
559tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
560{
561 int lock = 0;
562
563 switch (tv->v_type)
564 {
565 case VAR_BLOB:
566 if (tv->vval.v_blob != NULL)
567 lock = tv->vval.v_blob->bv_lock;
568 break;
569 case VAR_LIST:
570 if (tv->vval.v_list != NULL)
571 lock = tv->vval.v_list->lv_lock;
572 break;
573 case VAR_DICT:
574 if (tv->vval.v_dict != NULL)
575 lock = tv->vval.v_dict->dv_lock;
576 break;
577 default:
578 break;
579 }
Bram Moolenaara187c432020-09-16 21:08:28 +0200580 return value_check_lock(tv->v_lock, name, use_gettext)
581 || (lock != 0 && value_check_lock(lock, name, use_gettext));
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200582}
583
584/*
585 * Copy the values from typval_T "from" to typval_T "to".
586 * When needed allocates string or increases reference count.
587 * Does not make a copy of a list, blob or dict but copies the reference!
588 * It is OK for "from" and "to" to point to the same item. This is used to
589 * make a copy later.
590 */
591 void
592copy_tv(typval_T *from, typval_T *to)
593{
594 to->v_type = from->v_type;
595 to->v_lock = 0;
596 switch (from->v_type)
597 {
598 case VAR_NUMBER:
599 case VAR_BOOL:
600 case VAR_SPECIAL:
601 to->vval.v_number = from->vval.v_number;
602 break;
603 case VAR_FLOAT:
604#ifdef FEAT_FLOAT
605 to->vval.v_float = from->vval.v_float;
606 break;
607#endif
608 case VAR_JOB:
609#ifdef FEAT_JOB_CHANNEL
610 to->vval.v_job = from->vval.v_job;
611 if (to->vval.v_job != NULL)
612 ++to->vval.v_job->jv_refcount;
613 break;
614#endif
615 case VAR_CHANNEL:
616#ifdef FEAT_JOB_CHANNEL
617 to->vval.v_channel = from->vval.v_channel;
618 if (to->vval.v_channel != NULL)
619 ++to->vval.v_channel->ch_refcount;
620 break;
621#endif
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200622 case VAR_INSTR:
623 to->vval.v_instr = from->vval.v_instr;
624 break;
625
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200626 case VAR_STRING:
627 case VAR_FUNC:
628 if (from->vval.v_string == NULL)
629 to->vval.v_string = NULL;
630 else
631 {
632 to->vval.v_string = vim_strsave(from->vval.v_string);
633 if (from->v_type == VAR_FUNC)
634 func_ref(to->vval.v_string);
635 }
636 break;
637 case VAR_PARTIAL:
638 if (from->vval.v_partial == NULL)
639 to->vval.v_partial = NULL;
640 else
641 {
642 to->vval.v_partial = from->vval.v_partial;
643 ++to->vval.v_partial->pt_refcount;
644 }
645 break;
646 case VAR_BLOB:
647 if (from->vval.v_blob == NULL)
648 to->vval.v_blob = NULL;
649 else
650 {
651 to->vval.v_blob = from->vval.v_blob;
652 ++to->vval.v_blob->bv_refcount;
653 }
654 break;
655 case VAR_LIST:
656 if (from->vval.v_list == NULL)
657 to->vval.v_list = NULL;
658 else
659 {
660 to->vval.v_list = from->vval.v_list;
661 ++to->vval.v_list->lv_refcount;
662 }
663 break;
664 case VAR_DICT:
665 if (from->vval.v_dict == NULL)
666 to->vval.v_dict = NULL;
667 else
668 {
669 to->vval.v_dict = from->vval.v_dict;
670 ++to->vval.v_dict->dv_refcount;
671 }
672 break;
673 case VAR_UNKNOWN:
674 case VAR_ANY:
675 case VAR_VOID:
676 internal_error_no_abort("copy_tv(UNKNOWN)");
677 break;
678 }
679}
680
681/*
682 * Compare "typ1" and "typ2". Put the result in "typ1".
683 */
684 int
685typval_compare(
686 typval_T *typ1, // first operand
687 typval_T *typ2, // second operand
Bram Moolenaar657137c2021-01-09 15:45:23 +0100688 exprtype_T type, // operator
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200689 int ic) // ignore case
690{
691 int i;
692 varnumber_T n1, n2;
693 char_u *s1, *s2;
694 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
695 int type_is = type == EXPR_IS || type == EXPR_ISNOT;
696
697 if (type_is && typ1->v_type != typ2->v_type)
698 {
699 // For "is" a different type always means FALSE, for "notis"
700 // it means TRUE.
701 n1 = (type == EXPR_ISNOT);
702 }
703 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
704 {
705 if (type_is)
706 {
707 n1 = (typ1->v_type == typ2->v_type
708 && typ1->vval.v_blob == typ2->vval.v_blob);
709 if (type == EXPR_ISNOT)
710 n1 = !n1;
711 }
712 else if (typ1->v_type != typ2->v_type
713 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
714 {
715 if (typ1->v_type != typ2->v_type)
716 emsg(_("E977: Can only compare Blob with Blob"));
717 else
718 emsg(_(e_invalblob));
719 clear_tv(typ1);
720 return FAIL;
721 }
722 else
723 {
724 // Compare two Blobs for being equal or unequal.
725 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
726 if (type == EXPR_NEQUAL)
727 n1 = !n1;
728 }
729 }
730 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
731 {
732 if (type_is)
733 {
734 n1 = (typ1->v_type == typ2->v_type
735 && typ1->vval.v_list == typ2->vval.v_list);
736 if (type == EXPR_ISNOT)
737 n1 = !n1;
738 }
739 else if (typ1->v_type != typ2->v_type
740 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
741 {
742 if (typ1->v_type != typ2->v_type)
743 emsg(_("E691: Can only compare List with List"));
744 else
745 emsg(_("E692: Invalid operation for List"));
746 clear_tv(typ1);
747 return FAIL;
748 }
749 else
750 {
751 // Compare two Lists for being equal or unequal.
752 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
753 ic, FALSE);
754 if (type == EXPR_NEQUAL)
755 n1 = !n1;
756 }
757 }
758
759 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
760 {
761 if (type_is)
762 {
763 n1 = (typ1->v_type == typ2->v_type
764 && typ1->vval.v_dict == typ2->vval.v_dict);
765 if (type == EXPR_ISNOT)
766 n1 = !n1;
767 }
768 else if (typ1->v_type != typ2->v_type
769 || (type != EXPR_EQUAL && type != EXPR_NEQUAL))
770 {
771 if (typ1->v_type != typ2->v_type)
772 emsg(_("E735: Can only compare Dictionary with Dictionary"));
773 else
774 emsg(_("E736: Invalid operation for Dictionary"));
775 clear_tv(typ1);
776 return FAIL;
777 }
778 else
779 {
780 // Compare two Dictionaries for being equal or unequal.
781 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
782 ic, FALSE);
783 if (type == EXPR_NEQUAL)
784 n1 = !n1;
785 }
786 }
787
788 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
789 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
790 {
791 if (type != EXPR_EQUAL && type != EXPR_NEQUAL
792 && type != EXPR_IS && type != EXPR_ISNOT)
793 {
794 emsg(_("E694: Invalid operation for Funcrefs"));
795 clear_tv(typ1);
796 return FAIL;
797 }
798 if ((typ1->v_type == VAR_PARTIAL
799 && typ1->vval.v_partial == NULL)
800 || (typ2->v_type == VAR_PARTIAL
801 && typ2->vval.v_partial == NULL))
802 // When both partials are NULL, then they are equal.
803 // Otherwise they are not equal.
804 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
805 else if (type_is)
806 {
807 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
808 // strings are considered the same if their value is
809 // the same
810 n1 = tv_equal(typ1, typ2, ic, FALSE);
811 else if (typ1->v_type == VAR_PARTIAL
812 && typ2->v_type == VAR_PARTIAL)
813 n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
814 else
815 n1 = FALSE;
816 }
817 else
818 n1 = tv_equal(typ1, typ2, ic, FALSE);
819 if (type == EXPR_NEQUAL || type == EXPR_ISNOT)
820 n1 = !n1;
821 }
822
823#ifdef FEAT_FLOAT
824 // If one of the two variables is a float, compare as a float.
825 // When using "=~" or "!~", always compare as string.
826 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
827 && type != EXPR_MATCH && type != EXPR_NOMATCH)
828 {
829 float_T f1, f2;
830
831 f1 = tv_get_float(typ1);
832 f2 = tv_get_float(typ2);
833 n1 = FALSE;
834 switch (type)
835 {
836 case EXPR_IS:
837 case EXPR_EQUAL: n1 = (f1 == f2); break;
838 case EXPR_ISNOT:
839 case EXPR_NEQUAL: n1 = (f1 != f2); break;
840 case EXPR_GREATER: n1 = (f1 > f2); break;
841 case EXPR_GEQUAL: n1 = (f1 >= f2); break;
842 case EXPR_SMALLER: n1 = (f1 < f2); break;
843 case EXPR_SEQUAL: n1 = (f1 <= f2); break;
844 case EXPR_UNKNOWN:
845 case EXPR_MATCH:
846 default: break; // avoid gcc warning
847 }
848 }
849#endif
850
851 // If one of the two variables is a number, compare as a number.
852 // When using "=~" or "!~", always compare as string.
853 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
854 && type != EXPR_MATCH && type != EXPR_NOMATCH)
855 {
856 n1 = tv_get_number(typ1);
857 n2 = tv_get_number(typ2);
858 switch (type)
859 {
860 case EXPR_IS:
861 case EXPR_EQUAL: n1 = (n1 == n2); break;
862 case EXPR_ISNOT:
863 case EXPR_NEQUAL: n1 = (n1 != n2); break;
864 case EXPR_GREATER: n1 = (n1 > n2); break;
865 case EXPR_GEQUAL: n1 = (n1 >= n2); break;
866 case EXPR_SMALLER: n1 = (n1 < n2); break;
867 case EXPR_SEQUAL: n1 = (n1 <= n2); break;
868 case EXPR_UNKNOWN:
869 case EXPR_MATCH:
870 default: break; // avoid gcc warning
871 }
872 }
Bram Moolenaarcff40ff2021-01-09 16:21:37 +0100873 else if (in_vim9script() && (typ1->v_type == VAR_BOOL
874 || typ2->v_type == VAR_BOOL))
875 {
876 if (typ1->v_type != typ2->v_type)
877 {
878 semsg(_(e_cannot_compare_str_with_str),
879 vartype_name(typ1->v_type), vartype_name(typ2->v_type));
880 clear_tv(typ1);
881 return FAIL;
882 }
883 n1 = typ1->vval.v_number;
884 n2 = typ2->vval.v_number;
885 switch (type)
886 {
887 case EXPR_IS:
888 case EXPR_EQUAL: n1 = (n1 == n2); break;
889 case EXPR_ISNOT:
890 case EXPR_NEQUAL: n1 = (n1 != n2); break;
891 default:
892 emsg(_(e_invalid_operation_for_bool));
893 clear_tv(typ1);
894 return FAIL;
895 }
896 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200897 else
898 {
899 s1 = tv_get_string_buf(typ1, buf1);
900 s2 = tv_get_string_buf(typ2, buf2);
901 if (type != EXPR_MATCH && type != EXPR_NOMATCH)
902 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
903 else
904 i = 0;
905 n1 = FALSE;
906 switch (type)
907 {
908 case EXPR_IS:
909 case EXPR_EQUAL: n1 = (i == 0); break;
910 case EXPR_ISNOT:
911 case EXPR_NEQUAL: n1 = (i != 0); break;
912 case EXPR_GREATER: n1 = (i > 0); break;
913 case EXPR_GEQUAL: n1 = (i >= 0); break;
914 case EXPR_SMALLER: n1 = (i < 0); break;
915 case EXPR_SEQUAL: n1 = (i <= 0); break;
916
917 case EXPR_MATCH:
918 case EXPR_NOMATCH:
919 n1 = pattern_match(s2, s1, ic);
920 if (type == EXPR_NOMATCH)
921 n1 = !n1;
922 break;
923
924 default: break; // avoid gcc warning
925 }
926 }
927 clear_tv(typ1);
Bram Moolenaarc71f36a2020-07-21 21:31:00 +0200928 if (in_vim9script())
929 {
930 typ1->v_type = VAR_BOOL;
931 typ1->vval.v_number = n1 ? VVAL_TRUE : VVAL_FALSE;
932 }
933 else
934 {
935 typ1->v_type = VAR_NUMBER;
936 typ1->vval.v_number = n1;
937 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200938
939 return OK;
940}
941
Bram Moolenaar34453202021-01-31 13:08:38 +0100942/*
943 * Convert any type to a string, never give an error.
944 * When "quotes" is TRUE add quotes to a string.
945 * Returns an allocated string.
946 */
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200947 char_u *
Bram Moolenaar34453202021-01-31 13:08:38 +0100948typval_tostring(typval_T *arg, int quotes)
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200949{
950 char_u *tofree;
951 char_u numbuf[NUMBUFLEN];
952 char_u *ret = NULL;
953
954 if (arg == NULL)
955 return vim_strsave((char_u *)"(does not exist)");
Bram Moolenaar34453202021-01-31 13:08:38 +0100956 if (!quotes && arg->v_type == VAR_STRING)
957 {
958 ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
959 : arg->vval.v_string);
960 }
961 else
962 {
963 ret = tv2string(arg, &tofree, numbuf, 0);
964 // Make a copy if we have a value but it's not in allocated memory.
965 if (ret != NULL && tofree == NULL)
966 ret = vim_strsave(ret);
967 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +0200968 return ret;
969}
970
971/*
972 * Return TRUE if typeval "tv" is locked: Either that value is locked itself
973 * or it refers to a List or Dictionary that is locked.
974 */
975 int
976tv_islocked(typval_T *tv)
977{
978 return (tv->v_lock & VAR_LOCKED)
979 || (tv->v_type == VAR_LIST
980 && tv->vval.v_list != NULL
981 && (tv->vval.v_list->lv_lock & VAR_LOCKED))
982 || (tv->v_type == VAR_DICT
983 && tv->vval.v_dict != NULL
984 && (tv->vval.v_dict->dv_lock & VAR_LOCKED));
985}
986
987 static int
988func_equal(
989 typval_T *tv1,
990 typval_T *tv2,
991 int ic) // ignore case
992{
993 char_u *s1, *s2;
994 dict_T *d1, *d2;
995 int a1, a2;
996 int i;
997
998 // empty and NULL function name considered the same
999 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
1000 : partial_name(tv1->vval.v_partial);
1001 if (s1 != NULL && *s1 == NUL)
1002 s1 = NULL;
1003 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
1004 : partial_name(tv2->vval.v_partial);
1005 if (s2 != NULL && *s2 == NUL)
1006 s2 = NULL;
1007 if (s1 == NULL || s2 == NULL)
1008 {
1009 if (s1 != s2)
1010 return FALSE;
1011 }
1012 else if (STRCMP(s1, s2) != 0)
1013 return FALSE;
1014
1015 // empty dict and NULL dict is different
1016 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
1017 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
1018 if (d1 == NULL || d2 == NULL)
1019 {
1020 if (d1 != d2)
1021 return FALSE;
1022 }
1023 else if (!dict_equal(d1, d2, ic, TRUE))
1024 return FALSE;
1025
1026 // empty list and no list considered the same
1027 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
1028 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
1029 if (a1 != a2)
1030 return FALSE;
1031 for (i = 0; i < a1; ++i)
1032 if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
1033 tv2->vval.v_partial->pt_argv + i, ic, TRUE))
1034 return FALSE;
1035
1036 return TRUE;
1037}
1038
1039/*
1040 * Return TRUE if "tv1" and "tv2" have the same value.
1041 * Compares the items just like "==" would compare them, but strings and
1042 * numbers are different. Floats and numbers are also different.
1043 */
1044 int
1045tv_equal(
1046 typval_T *tv1,
1047 typval_T *tv2,
1048 int ic, // ignore case
1049 int recursive) // TRUE when used recursively
1050{
1051 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1052 char_u *s1, *s2;
1053 static int recursive_cnt = 0; // catch recursive loops
1054 int r;
1055 static int tv_equal_recurse_limit;
1056
1057 // Catch lists and dicts that have an endless loop by limiting
1058 // recursiveness to a limit. We guess they are equal then.
1059 // A fixed limit has the problem of still taking an awful long time.
1060 // Reduce the limit every time running into it. That should work fine for
1061 // deeply linked structures that are not recursively linked and catch
1062 // recursiveness quickly.
1063 if (!recursive)
1064 tv_equal_recurse_limit = 1000;
1065 if (recursive_cnt >= tv_equal_recurse_limit)
1066 {
1067 --tv_equal_recurse_limit;
1068 return TRUE;
1069 }
1070
1071 // For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and
1072 // arguments.
1073 if ((tv1->v_type == VAR_FUNC
1074 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
1075 && (tv2->v_type == VAR_FUNC
1076 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
1077 {
1078 ++recursive_cnt;
1079 r = func_equal(tv1, tv2, ic);
1080 --recursive_cnt;
1081 return r;
1082 }
1083
Bram Moolenaar418a29f2021-02-10 22:23:41 +01001084 if (tv1->v_type != tv2->v_type
1085 && ((tv1->v_type != VAR_BOOL && tv1->v_type != VAR_SPECIAL)
1086 || (tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL)))
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001087 return FALSE;
1088
1089 switch (tv1->v_type)
1090 {
1091 case VAR_LIST:
1092 ++recursive_cnt;
1093 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
1094 --recursive_cnt;
1095 return r;
1096
1097 case VAR_DICT:
1098 ++recursive_cnt;
1099 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
1100 --recursive_cnt;
1101 return r;
1102
1103 case VAR_BLOB:
1104 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
1105
1106 case VAR_NUMBER:
1107 case VAR_BOOL:
1108 case VAR_SPECIAL:
1109 return tv1->vval.v_number == tv2->vval.v_number;
1110
1111 case VAR_STRING:
1112 s1 = tv_get_string_buf(tv1, buf1);
1113 s2 = tv_get_string_buf(tv2, buf2);
1114 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
1115
1116 case VAR_FLOAT:
1117#ifdef FEAT_FLOAT
1118 return tv1->vval.v_float == tv2->vval.v_float;
1119#endif
1120 case VAR_JOB:
1121#ifdef FEAT_JOB_CHANNEL
1122 return tv1->vval.v_job == tv2->vval.v_job;
1123#endif
1124 case VAR_CHANNEL:
1125#ifdef FEAT_JOB_CHANNEL
1126 return tv1->vval.v_channel == tv2->vval.v_channel;
1127#endif
Bram Moolenaarf18332f2021-05-07 17:55:55 +02001128 case VAR_INSTR:
1129 return tv1->vval.v_instr == tv2->vval.v_instr;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001130
1131 case VAR_PARTIAL:
1132 return tv1->vval.v_partial == tv2->vval.v_partial;
1133
1134 case VAR_FUNC:
1135 return tv1->vval.v_string == tv2->vval.v_string;
1136
1137 case VAR_UNKNOWN:
1138 case VAR_ANY:
1139 case VAR_VOID:
1140 break;
1141 }
1142
1143 // VAR_UNKNOWN can be the result of a invalid expression, let's say it
1144 // does not equal anything, not even itself.
1145 return FALSE;
1146}
1147
1148/*
1149 * Get an option value.
1150 * "arg" points to the '&' or '+' before the option name.
1151 * "arg" is advanced to character after the option name.
1152 * Return OK or FAIL.
1153 */
1154 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001155eval_option(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001156 char_u **arg,
1157 typval_T *rettv, // when NULL, only check if option exists
1158 int evaluate)
1159{
1160 char_u *option_end;
1161 long numval;
1162 char_u *stringval;
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001163 getoption_T opt_type;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001164 int c;
1165 int working = (**arg == '+'); // has("+option")
1166 int ret = OK;
1167 int opt_flags;
1168
1169 // Isolate the option name and find its value.
1170 option_end = find_option_end(arg, &opt_flags);
1171 if (option_end == NULL)
1172 {
1173 if (rettv != NULL)
1174 semsg(_("E112: Option name missing: %s"), *arg);
1175 return FAIL;
1176 }
1177
1178 if (!evaluate)
1179 {
1180 *arg = option_end;
1181 return OK;
1182 }
1183
1184 c = *option_end;
1185 *option_end = NUL;
1186 opt_type = get_option_value(*arg, &numval,
1187 rettv == NULL ? NULL : &stringval, opt_flags);
1188
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001189 if (opt_type == gov_unknown)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001190 {
1191 if (rettv != NULL)
1192 semsg(_(e_unknown_option), *arg);
1193 ret = FAIL;
1194 }
1195 else if (rettv != NULL)
1196 {
Bram Moolenaara79925a2021-01-05 17:50:28 +01001197 rettv->v_lock = 0;
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001198 if (opt_type == gov_hidden_string)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001199 {
1200 rettv->v_type = VAR_STRING;
1201 rettv->vval.v_string = NULL;
1202 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001203 else if (opt_type == gov_hidden_bool || opt_type == gov_hidden_number)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001204 {
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001205 rettv->v_type = in_vim9script() && opt_type == gov_hidden_bool
1206 ? VAR_BOOL : VAR_NUMBER;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001207 rettv->vval.v_number = 0;
1208 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001209 else if (opt_type == gov_bool || opt_type == gov_number)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001210 {
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001211 if (in_vim9script() && opt_type == gov_bool)
1212 {
1213 rettv->v_type = VAR_BOOL;
1214 rettv->vval.v_number = numval ? VVAL_TRUE : VVAL_FALSE;
1215 }
1216 else
1217 {
1218 rettv->v_type = VAR_NUMBER;
1219 rettv->vval.v_number = numval;
1220 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001221 }
1222 else // string option
1223 {
1224 rettv->v_type = VAR_STRING;
1225 rettv->vval.v_string = stringval;
1226 }
1227 }
Bram Moolenaardd1f4262020-12-31 17:41:01 +01001228 else if (working && (opt_type == gov_hidden_bool
1229 || opt_type == gov_hidden_number
1230 || opt_type == gov_hidden_string))
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001231 ret = FAIL;
1232
1233 *option_end = c; // put back for error messages
1234 *arg = option_end;
1235
1236 return ret;
1237}
1238
1239/*
1240 * Allocate a variable for a number constant. Also deals with "0z" for blob.
1241 * Return OK or FAIL.
1242 */
1243 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001244eval_number(
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001245 char_u **arg,
1246 typval_T *rettv,
1247 int evaluate,
1248 int want_string UNUSED)
1249{
1250 int len;
1251#ifdef FEAT_FLOAT
1252 char_u *p;
1253 int get_float = FALSE;
1254
1255 // We accept a float when the format matches
1256 // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
1257 // strict to avoid backwards compatibility problems.
1258 // With script version 2 and later the leading digit can be
1259 // omitted.
1260 // Don't look for a float after the "." operator, so that
1261 // ":let vers = 1.2.3" doesn't fail.
1262 if (**arg == '.')
1263 p = *arg;
1264 else
1265 p = skipdigits(*arg + 1);
1266 if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
1267 {
1268 get_float = TRUE;
1269 p = skipdigits(p + 2);
1270 if (*p == 'e' || *p == 'E')
1271 {
1272 ++p;
1273 if (*p == '-' || *p == '+')
1274 ++p;
1275 if (!vim_isdigit(*p))
1276 get_float = FALSE;
1277 else
1278 p = skipdigits(p + 1);
1279 }
1280 if (ASCII_ISALPHA(*p) || *p == '.')
1281 get_float = FALSE;
1282 }
1283 if (get_float)
1284 {
1285 float_T f;
1286
1287 *arg += string2float(*arg, &f);
1288 if (evaluate)
1289 {
1290 rettv->v_type = VAR_FLOAT;
1291 rettv->vval.v_float = f;
1292 }
1293 }
1294 else
1295#endif
1296 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
1297 {
1298 char_u *bp;
1299 blob_T *blob = NULL; // init for gcc
1300
1301 // Blob constant: 0z0123456789abcdef
1302 if (evaluate)
1303 blob = blob_alloc();
1304 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
1305 {
1306 if (!vim_isxdigit(bp[1]))
1307 {
1308 if (blob != NULL)
1309 {
1310 emsg(_("E973: Blob literal should have an even number of hex characters"));
1311 ga_clear(&blob->bv_ga);
1312 VIM_CLEAR(blob);
1313 }
1314 return FAIL;
1315 }
1316 if (blob != NULL)
1317 ga_append(&blob->bv_ga,
1318 (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
1319 if (bp[2] == '.' && vim_isxdigit(bp[3]))
1320 ++bp;
1321 }
1322 if (blob != NULL)
1323 rettv_blob_set(rettv, blob);
1324 *arg = bp;
1325 }
1326 else
1327 {
1328 varnumber_T n;
1329
1330 // decimal, hex or octal number
1331 vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4
1332 ? STR2NR_NO_OCT + STR2NR_QUOTE
1333 : STR2NR_ALL, &n, NULL, 0, TRUE);
1334 if (len == 0)
1335 {
1336 semsg(_(e_invexpr2), *arg);
1337 return FAIL;
1338 }
1339 *arg += len;
1340 if (evaluate)
1341 {
1342 rettv->v_type = VAR_NUMBER;
1343 rettv->vval.v_number = n;
1344 }
1345 }
1346 return OK;
1347}
1348
1349/*
1350 * Allocate a variable for a string constant.
1351 * Return OK or FAIL.
1352 */
1353 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001354eval_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001355{
1356 char_u *p;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001357 char_u *end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001358 int extra = 0;
1359 int len;
1360
1361 // Find the end of the string, skipping backslashed characters.
1362 for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p))
1363 {
1364 if (*p == '\\' && p[1] != NUL)
1365 {
1366 ++p;
1367 // A "\<x>" form occupies at least 4 characters, and produces up
1368 // to 21 characters (3 * 6 for the char and 3 for a modifier):
1369 // reserve space for 18 extra.
1370 // Each byte in the char could be encoded as K_SPECIAL K_EXTRA x.
1371 if (*p == '<')
1372 extra += 18;
1373 }
1374 }
1375
1376 if (*p != '"')
1377 {
1378 semsg(_("E114: Missing quote: %s"), *arg);
1379 return FAIL;
1380 }
1381
1382 // If only parsing, set *arg and return here
1383 if (!evaluate)
1384 {
1385 *arg = p + 1;
1386 return OK;
1387 }
1388
1389 // Copy the string into allocated memory, handling backslashed
1390 // characters.
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001391 rettv->v_type = VAR_STRING;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001392 len = (int)(p - *arg + extra);
1393 rettv->vval.v_string = alloc(len);
1394 if (rettv->vval.v_string == NULL)
1395 return FAIL;
1396 end = rettv->vval.v_string;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001397
1398 for (p = *arg + 1; *p != NUL && *p != '"'; )
1399 {
1400 if (*p == '\\')
1401 {
1402 switch (*++p)
1403 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001404 case 'b': *end++ = BS; ++p; break;
1405 case 'e': *end++ = ESC; ++p; break;
1406 case 'f': *end++ = FF; ++p; break;
1407 case 'n': *end++ = NL; ++p; break;
1408 case 'r': *end++ = CAR; ++p; break;
1409 case 't': *end++ = TAB; ++p; break;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001410
1411 case 'X': // hex: "\x1", "\x12"
1412 case 'x':
1413 case 'u': // Unicode: "\u0023"
1414 case 'U':
1415 if (vim_isxdigit(p[1]))
1416 {
1417 int n, nr;
1418 int c = toupper(*p);
1419
1420 if (c == 'X')
1421 n = 2;
1422 else if (*p == 'u')
1423 n = 4;
1424 else
1425 n = 8;
1426 nr = 0;
1427 while (--n >= 0 && vim_isxdigit(p[1]))
1428 {
1429 ++p;
1430 nr = (nr << 4) + hex2nr(*p);
1431 }
1432 ++p;
1433 // For "\u" store the number according to
1434 // 'encoding'.
1435 if (c != 'X')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001436 end += (*mb_char2bytes)(nr, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001437 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001438 *end++ = nr;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001439 }
1440 break;
1441
1442 // octal: "\1", "\12", "\123"
1443 case '0':
1444 case '1':
1445 case '2':
1446 case '3':
1447 case '4':
1448 case '5':
1449 case '6':
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001450 case '7': *end = *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001451 if (*p >= '0' && *p <= '7')
1452 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001453 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001454 if (*p >= '0' && *p <= '7')
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001455 *end = (*end << 3) + *p++ - '0';
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001456 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001457 ++end;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001458 break;
1459
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001460 // Special key, e.g.: "\<C-W>"
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001461 case '<':
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001462 {
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001463 int flags = FSK_KEYCODE | FSK_IN_STRING;
1464
Bram Moolenaarfccd93f2020-05-31 22:06:51 +02001465 if (p[1] != '*')
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001466 flags |= FSK_SIMPLIFY;
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001467 extra = trans_special(&p, end, flags, NULL);
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001468 if (extra != 0)
1469 {
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001470 end += extra;
1471 if (end >= rettv->vval.v_string + len)
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001472 iemsg("eval_string() used more space than allocated");
Bram Moolenaarebe9d342020-05-30 21:52:54 +02001473 break;
1474 }
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001475 }
1476 // FALLTHROUGH
1477
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001478 default: MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001479 break;
1480 }
1481 }
1482 else
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001483 MB_COPY_CHAR(p, end);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001484 }
Bram Moolenaar1e0b7b12020-06-19 19:30:53 +02001485 *end = NUL;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001486 if (*p != NUL) // just in case
1487 ++p;
1488 *arg = p;
1489
1490 return OK;
1491}
1492
1493/*
1494 * Allocate a variable for a 'str''ing' constant.
1495 * Return OK or FAIL.
1496 */
1497 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001498eval_lit_string(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001499{
1500 char_u *p;
1501 char_u *str;
1502 int reduce = 0;
1503
1504 // Find the end of the string, skipping ''.
1505 for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p))
1506 {
1507 if (*p == '\'')
1508 {
1509 if (p[1] != '\'')
1510 break;
1511 ++reduce;
1512 ++p;
1513 }
1514 }
1515
1516 if (*p != '\'')
1517 {
1518 semsg(_("E115: Missing quote: %s"), *arg);
1519 return FAIL;
1520 }
1521
1522 // If only parsing return after setting "*arg"
1523 if (!evaluate)
1524 {
1525 *arg = p + 1;
1526 return OK;
1527 }
1528
1529 // Copy the string into allocated memory, handling '' to ' reduction.
1530 str = alloc((p - *arg) - reduce);
1531 if (str == NULL)
1532 return FAIL;
1533 rettv->v_type = VAR_STRING;
1534 rettv->vval.v_string = str;
1535
1536 for (p = *arg + 1; *p != NUL; )
1537 {
1538 if (*p == '\'')
1539 {
1540 if (p[1] != '\'')
1541 break;
1542 ++p;
1543 }
1544 MB_COPY_CHAR(p, str);
1545 }
1546 *str = NUL;
1547 *arg = p + 1;
1548
1549 return OK;
1550}
1551
1552/*
1553 * Return a string with the string representation of a variable.
1554 * If the memory is allocated "tofree" is set to it, otherwise NULL.
1555 * "numbuf" is used for a number.
1556 * Puts quotes around strings, so that they can be parsed back by eval().
1557 * May return NULL.
1558 */
1559 char_u *
1560tv2string(
1561 typval_T *tv,
1562 char_u **tofree,
1563 char_u *numbuf,
1564 int copyID)
1565{
1566 return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
1567}
1568
1569/*
1570 * Get the value of an environment variable.
1571 * "arg" is pointing to the '$'. It is advanced to after the name.
1572 * If the environment variable was not set, silently assume it is empty.
1573 * Return FAIL if the name is invalid.
1574 */
1575 int
Bram Moolenaar9a78e6d2020-07-01 18:29:55 +02001576eval_env_var(char_u **arg, typval_T *rettv, int evaluate)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001577{
1578 char_u *string = NULL;
1579 int len;
1580 int cc;
1581 char_u *name;
1582 int mustfree = FALSE;
1583
1584 ++*arg;
1585 name = *arg;
1586 len = get_env_len(arg);
1587 if (evaluate)
1588 {
1589 if (len == 0)
1590 return FAIL; // invalid empty name
1591
1592 cc = name[len];
1593 name[len] = NUL;
1594 // first try vim_getenv(), fast for normal environment vars
1595 string = vim_getenv(name, &mustfree);
1596 if (string != NULL && *string != NUL)
1597 {
1598 if (!mustfree)
1599 string = vim_strsave(string);
1600 }
1601 else
1602 {
1603 if (mustfree)
1604 vim_free(string);
1605
1606 // next try expanding things like $VIM and ${HOME}
1607 string = expand_env_save(name - 1);
1608 if (string != NULL && *string == '$')
1609 VIM_CLEAR(string);
1610 }
1611 name[len] = cc;
1612
1613 rettv->v_type = VAR_STRING;
1614 rettv->vval.v_string = string;
1615 }
1616
1617 return OK;
1618}
1619
1620/*
1621 * Get the lnum from the first argument.
1622 * Also accepts ".", "$", etc., but that only works for the current buffer.
1623 * Returns -1 on error.
1624 */
1625 linenr_T
1626tv_get_lnum(typval_T *argvars)
1627{
Bram Moolenaar9a963372020-12-21 21:58:46 +01001628 linenr_T lnum = -1;
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001629
Bram Moolenaar56acb092020-08-16 14:48:19 +02001630 if (argvars[0].v_type != VAR_STRING || !in_vim9script())
1631 lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL);
Bram Moolenaarf6bdd822021-03-28 16:26:41 +02001632 if (lnum <= 0 && argvars[0].v_type != VAR_NUMBER)
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001633 {
1634 int fnum;
Bram Moolenaar6f02b002021-01-10 20:22:54 +01001635 pos_T *fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE);
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001636
Bram Moolenaarf6bdd822021-03-28 16:26:41 +02001637 // no valid number, try using arg like line()
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001638 if (fp != NULL)
1639 lnum = fp->lnum;
1640 }
1641 return lnum;
1642}
1643
1644/*
1645 * Get the lnum from the first argument.
1646 * Also accepts "$", then "buf" is used.
1647 * Returns 0 on error.
1648 */
1649 linenr_T
1650tv_get_lnum_buf(typval_T *argvars, buf_T *buf)
1651{
1652 if (argvars[0].v_type == VAR_STRING
1653 && argvars[0].vval.v_string != NULL
1654 && argvars[0].vval.v_string[0] == '$'
1655 && buf != NULL)
1656 return buf->b_ml.ml_line_count;
1657 return (linenr_T)tv_get_number_chk(&argvars[0], NULL);
1658}
1659
1660/*
1661 * Get buffer by number or pattern.
1662 */
1663 buf_T *
1664tv_get_buf(typval_T *tv, int curtab_only)
1665{
1666 char_u *name = tv->vval.v_string;
1667 buf_T *buf;
1668
1669 if (tv->v_type == VAR_NUMBER)
1670 return buflist_findnr((int)tv->vval.v_number);
1671 if (tv->v_type != VAR_STRING)
1672 return NULL;
1673 if (name == NULL || *name == NUL)
1674 return curbuf;
1675 if (name[0] == '$' && name[1] == NUL)
1676 return lastbuf;
1677
1678 buf = buflist_find_by_name(name, curtab_only);
1679
1680 // If not found, try expanding the name, like done for bufexists().
1681 if (buf == NULL)
1682 buf = find_buffer(tv);
1683
1684 return buf;
1685}
1686
Bram Moolenaar3767e3a2020-09-01 23:06:01 +02001687/*
1688 * Like tv_get_buf() but give an error message is the type is wrong.
1689 */
1690 buf_T *
1691tv_get_buf_from_arg(typval_T *tv)
1692{
1693 buf_T *buf;
1694
1695 ++emsg_off;
1696 buf = tv_get_buf(tv, FALSE);
1697 --emsg_off;
1698 if (buf == NULL
1699 && tv->v_type != VAR_NUMBER
1700 && tv->v_type != VAR_STRING)
1701 // issue errmsg for type error
1702 (void)tv_get_number(tv);
1703 return buf;
1704}
1705
Bram Moolenaar367d59e2020-05-30 17:06:14 +02001706#endif // FEAT_EVAL