xref: /vim-8.2.3635/src/dict.c (revision 4c295027)
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  * dict.c: Dictionary support
12  */
13 
14 #include "vim.h"
15 
16 #if defined(FEAT_EVAL) || defined(PROTO)
17 
18 // List head for garbage collection. Although there can be a reference loop
19 // from partial to dict to partial, we don't need to keep track of the partial,
20 // since it will get freed when the dict is unused and gets freed.
21 static dict_T		*first_dict = NULL;
22 
23 /*
24  * Allocate an empty header for a dictionary.
25  * Caller should take care of the reference count.
26  */
27     dict_T *
28 dict_alloc(void)
29 {
30     dict_T *d;
31 
32     d = ALLOC_CLEAR_ONE(dict_T);
33     if (d != NULL)
34     {
35 	// Add the dict to the list of dicts for garbage collection.
36 	if (first_dict != NULL)
37 	    first_dict->dv_used_prev = d;
38 	d->dv_used_next = first_dict;
39 	d->dv_used_prev = NULL;
40 	first_dict = d;
41 
42 	hash_init(&d->dv_hashtab);
43 	d->dv_lock = 0;
44 	d->dv_scope = 0;
45 	d->dv_refcount = 0;
46 	d->dv_copyID = 0;
47     }
48     return d;
49 }
50 
51 /*
52  * dict_alloc() with an ID for alloc_fail().
53  */
54     dict_T *
55 dict_alloc_id(alloc_id_T id UNUSED)
56 {
57 #ifdef FEAT_EVAL
58     if (alloc_fail_id == id && alloc_does_fail(sizeof(list_T)))
59 	return NULL;
60 #endif
61     return (dict_alloc());
62 }
63 
64     dict_T *
65 dict_alloc_lock(int lock)
66 {
67     dict_T *d = dict_alloc();
68 
69     if (d != NULL)
70 	d->dv_lock = lock;
71     return d;
72 }
73 
74 /*
75  * Allocate an empty dict for a return value.
76  * Returns OK or FAIL.
77  */
78     int
79 rettv_dict_alloc(typval_T *rettv)
80 {
81     dict_T	*d = dict_alloc_lock(0);
82 
83     if (d == NULL)
84 	return FAIL;
85 
86     rettv_dict_set(rettv, d);
87     return OK;
88 }
89 
90 /*
91  * Set a dictionary as the return value
92  */
93     void
94 rettv_dict_set(typval_T *rettv, dict_T *d)
95 {
96     rettv->v_type = VAR_DICT;
97     rettv->vval.v_dict = d;
98     if (d != NULL)
99 	++d->dv_refcount;
100 }
101 
102 /*
103  * Free a Dictionary, including all non-container items it contains.
104  * Ignores the reference count.
105  */
106     void
107 dict_free_contents(dict_T *d)
108 {
109     hashtab_free_contents(&d->dv_hashtab);
110     free_type(d->dv_type);
111     d->dv_type = NULL;
112 }
113 
114 /*
115  * Clear hashtab "ht" and dict items it contains.
116  * If "ht" is not freed then you should call hash_init() next!
117  */
118     void
119 hashtab_free_contents(hashtab_T *ht)
120 {
121     int		todo;
122     hashitem_T	*hi;
123     dictitem_T	*di;
124 
125     // Lock the hashtab, we don't want it to resize while freeing items.
126     hash_lock(ht);
127     todo = (int)ht->ht_used;
128     for (hi = ht->ht_array; todo > 0; ++hi)
129     {
130 	if (!HASHITEM_EMPTY(hi))
131 	{
132 	    // Remove the item before deleting it, just in case there is
133 	    // something recursive causing trouble.
134 	    di = HI2DI(hi);
135 	    hash_remove(ht, hi);
136 	    dictitem_free(di);
137 	    --todo;
138 	}
139     }
140 
141     // The hashtab is still locked, it has to be re-initialized anyway.
142     hash_clear(ht);
143 }
144 
145     static void
146 dict_free_dict(dict_T *d)
147 {
148     // Remove the dict from the list of dicts for garbage collection.
149     if (d->dv_used_prev == NULL)
150 	first_dict = d->dv_used_next;
151     else
152 	d->dv_used_prev->dv_used_next = d->dv_used_next;
153     if (d->dv_used_next != NULL)
154 	d->dv_used_next->dv_used_prev = d->dv_used_prev;
155     vim_free(d);
156 }
157 
158     static void
159 dict_free(dict_T *d)
160 {
161     if (!in_free_unref_items)
162     {
163 	dict_free_contents(d);
164 	dict_free_dict(d);
165     }
166 }
167 
168 /*
169  * Unreference a Dictionary: decrement the reference count and free it when it
170  * becomes zero.
171  */
172     void
173 dict_unref(dict_T *d)
174 {
175     if (d != NULL && --d->dv_refcount <= 0)
176 	dict_free(d);
177 }
178 
179 /*
180  * Go through the list of dicts and free items without the copyID.
181  * Returns TRUE if something was freed.
182  */
183     int
184 dict_free_nonref(int copyID)
185 {
186     dict_T	*dd;
187     int		did_free = FALSE;
188 
189     for (dd = first_dict; dd != NULL; dd = dd->dv_used_next)
190 	if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
191 	{
192 	    // Free the Dictionary and ordinary items it contains, but don't
193 	    // recurse into Lists and Dictionaries, they will be in the list
194 	    // of dicts or list of lists.
195 	    dict_free_contents(dd);
196 	    did_free = TRUE;
197 	}
198     return did_free;
199 }
200 
201     void
202 dict_free_items(int copyID)
203 {
204     dict_T	*dd, *dd_next;
205 
206     for (dd = first_dict; dd != NULL; dd = dd_next)
207     {
208 	dd_next = dd->dv_used_next;
209 	if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
210 	    dict_free_dict(dd);
211     }
212 }
213 
214 /*
215  * Allocate a Dictionary item.
216  * The "key" is copied to the new item.
217  * Note that the type and value of the item "di_tv" still needs to be
218  * initialized!
219  * Returns NULL when out of memory.
220  */
221     dictitem_T *
222 dictitem_alloc(char_u *key)
223 {
224     dictitem_T *di;
225 
226     di = alloc(offsetof(dictitem_T, di_key) + STRLEN(key) + 1);
227     if (di != NULL)
228     {
229 	STRCPY(di->di_key, key);
230 	di->di_flags = DI_FLAGS_ALLOC;
231 	di->di_tv.v_lock = 0;
232     }
233     return di;
234 }
235 
236 /*
237  * Make a copy of a Dictionary item.
238  */
239     static dictitem_T *
240 dictitem_copy(dictitem_T *org)
241 {
242     dictitem_T *di;
243     size_t	len = STRLEN(org->di_key);
244 
245     di = alloc(offsetof(dictitem_T, di_key) + len + 1);
246     if (di != NULL)
247     {
248 	mch_memmove(di->di_key, org->di_key, len + 1);
249 	di->di_flags = DI_FLAGS_ALLOC;
250 	copy_tv(&org->di_tv, &di->di_tv);
251     }
252     return di;
253 }
254 
255 /*
256  * Remove item "item" from Dictionary "dict" and free it.
257  */
258     void
259 dictitem_remove(dict_T *dict, dictitem_T *item)
260 {
261     hashitem_T	*hi;
262 
263     hi = hash_find(&dict->dv_hashtab, item->di_key);
264     if (HASHITEM_EMPTY(hi))
265 	internal_error("dictitem_remove()");
266     else
267 	hash_remove(&dict->dv_hashtab, hi);
268     dictitem_free(item);
269 }
270 
271 /*
272  * Free a dict item.  Also clears the value.
273  */
274     void
275 dictitem_free(dictitem_T *item)
276 {
277     clear_tv(&item->di_tv);
278     if (item->di_flags & DI_FLAGS_ALLOC)
279 	vim_free(item);
280 }
281 
282 /*
283  * Make a copy of dict "d".  Shallow if "deep" is FALSE.
284  * The refcount of the new dict is set to 1.
285  * See item_copy() for "copyID".
286  * Returns NULL when out of memory.
287  */
288     dict_T *
289 dict_copy(dict_T *orig, int deep, int copyID)
290 {
291     dict_T	*copy;
292     dictitem_T	*di;
293     int		todo;
294     hashitem_T	*hi;
295 
296     if (orig == NULL)
297 	return NULL;
298 
299     copy = dict_alloc();
300     if (copy != NULL)
301     {
302 	if (copyID != 0)
303 	{
304 	    orig->dv_copyID = copyID;
305 	    orig->dv_copydict = copy;
306 	}
307 	todo = (int)orig->dv_hashtab.ht_used;
308 	for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
309 	{
310 	    if (!HASHITEM_EMPTY(hi))
311 	    {
312 		--todo;
313 
314 		di = dictitem_alloc(hi->hi_key);
315 		if (di == NULL)
316 		    break;
317 		if (deep)
318 		{
319 		    if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
320 							      copyID) == FAIL)
321 		    {
322 			vim_free(di);
323 			break;
324 		    }
325 		}
326 		else
327 		    copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
328 		if (dict_add(copy, di) == FAIL)
329 		{
330 		    dictitem_free(di);
331 		    break;
332 		}
333 	    }
334 	}
335 
336 	++copy->dv_refcount;
337 	if (todo > 0)
338 	{
339 	    dict_unref(copy);
340 	    copy = NULL;
341 	}
342     }
343 
344     return copy;
345 }
346 
347 /*
348  * Add item "item" to Dictionary "d".
349  * Returns FAIL when out of memory and when key already exists.
350  */
351     int
352 dict_add(dict_T *d, dictitem_T *item)
353 {
354     return hash_add(&d->dv_hashtab, item->di_key);
355 }
356 
357 /*
358  * Add a number or special entry to dictionary "d".
359  * Returns FAIL when out of memory and when key already exists.
360  */
361     static int
362 dict_add_number_special(dict_T *d, char *key, varnumber_T nr, vartype_T vartype)
363 {
364     dictitem_T	*item;
365 
366     item = dictitem_alloc((char_u *)key);
367     if (item == NULL)
368 	return FAIL;
369     item->di_tv.v_type = vartype;
370     item->di_tv.vval.v_number = nr;
371     if (dict_add(d, item) == FAIL)
372     {
373 	dictitem_free(item);
374 	return FAIL;
375     }
376     return OK;
377 }
378 
379 /*
380  * Add a number entry to dictionary "d".
381  * Returns FAIL when out of memory and when key already exists.
382  */
383     int
384 dict_add_number(dict_T *d, char *key, varnumber_T nr)
385 {
386     return dict_add_number_special(d, key, nr, VAR_NUMBER);
387 }
388 
389 /*
390  * Add a special entry to dictionary "d".
391  * Returns FAIL when out of memory and when key already exists.
392  */
393     int
394 dict_add_bool(dict_T *d, char *key, varnumber_T nr)
395 {
396     return dict_add_number_special(d, key, nr, VAR_BOOL);
397 }
398 
399 /*
400  * Add a string entry to dictionary "d".
401  * Returns FAIL when out of memory and when key already exists.
402  */
403     int
404 dict_add_string(dict_T *d, char *key, char_u *str)
405 {
406     return dict_add_string_len(d, key, str, -1);
407 }
408 
409 /*
410  * Add a string entry to dictionary "d".
411  * "str" will be copied to allocated memory.
412  * When "len" is -1 use the whole string, otherwise only this many bytes.
413  * Returns FAIL when out of memory and when key already exists.
414  */
415     int
416 dict_add_string_len(dict_T *d, char *key, char_u *str, int len)
417 {
418     dictitem_T	*item;
419     char_u	*val = NULL;
420 
421     item = dictitem_alloc((char_u *)key);
422     if (item == NULL)
423 	return FAIL;
424     item->di_tv.v_type = VAR_STRING;
425     if (str != NULL)
426     {
427 	if (len == -1)
428 	    val = vim_strsave(str);
429 	else
430 	    val = vim_strnsave(str, len);
431     }
432     item->di_tv.vval.v_string = val;
433     if (dict_add(d, item) == FAIL)
434     {
435 	dictitem_free(item);
436 	return FAIL;
437     }
438     return OK;
439 }
440 
441 /*
442  * Add a list entry to dictionary "d".
443  * Returns FAIL when out of memory and when key already exists.
444  */
445     int
446 dict_add_list(dict_T *d, char *key, list_T *list)
447 {
448     dictitem_T	*item;
449 
450     item = dictitem_alloc((char_u *)key);
451     if (item == NULL)
452 	return FAIL;
453     item->di_tv.v_type = VAR_LIST;
454     item->di_tv.vval.v_list = list;
455     ++list->lv_refcount;
456     if (dict_add(d, item) == FAIL)
457     {
458 	dictitem_free(item);
459 	return FAIL;
460     }
461     return OK;
462 }
463 
464 /*
465  * Add a typval_T entry to dictionary "d".
466  * Returns FAIL when out of memory and when key already exists.
467  */
468     int
469 dict_add_tv(dict_T *d, char *key, typval_T *tv)
470 {
471     dictitem_T	*item;
472 
473     item = dictitem_alloc((char_u *)key);
474     if (item == NULL)
475 	return FAIL;
476     copy_tv(tv, &item->di_tv);
477     if (dict_add(d, item) == FAIL)
478     {
479 	dictitem_free(item);
480 	return FAIL;
481     }
482     return OK;
483 }
484 
485 /*
486  * Add a callback to dictionary "d".
487  * Returns FAIL when out of memory and when key already exists.
488  */
489     int
490 dict_add_callback(dict_T *d, char *key, callback_T *cb)
491 {
492     dictitem_T	*item;
493 
494     item = dictitem_alloc((char_u *)key);
495     if (item == NULL)
496 	return FAIL;
497     put_callback(cb, &item->di_tv);
498     if (dict_add(d, item) == FAIL)
499     {
500 	dictitem_free(item);
501 	return FAIL;
502     }
503     return OK;
504 }
505 
506 /*
507  * Initializes "iter" for iterating over dictionary items with
508  * dict_iterate_next().
509  * If "var" is not a Dict or an empty Dict then there will be nothing to
510  * iterate over, no error is given.
511  * NOTE: The dictionary must not change until iterating is finished!
512  */
513     void
514 dict_iterate_start(typval_T *var, dict_iterator_T *iter)
515 {
516     if (var->v_type != VAR_DICT || var->vval.v_dict == NULL)
517 	iter->dit_todo = 0;
518     else
519     {
520 	dict_T	*d = var->vval.v_dict;
521 
522 	iter->dit_todo = d->dv_hashtab.ht_used;
523 	iter->dit_hi = d->dv_hashtab.ht_array;
524     }
525 }
526 
527 /*
528  * Iterate over the items referred to by "iter".  It should be initialized with
529  * dict_iterate_start().
530  * Returns a pointer to the key.
531  * "*tv_result" is set to point to the value for that key.
532  * If there are no more items, NULL is returned.
533  */
534     char_u *
535 dict_iterate_next(dict_iterator_T *iter, typval_T **tv_result)
536 {
537     dictitem_T	*di;
538     char_u      *result;
539 
540     if (iter->dit_todo == 0)
541 	return NULL;
542 
543     while (HASHITEM_EMPTY(iter->dit_hi))
544 	++iter->dit_hi;
545 
546     di = HI2DI(iter->dit_hi);
547     result = di->di_key;
548     *tv_result = &di->di_tv;
549 
550     --iter->dit_todo;
551     ++iter->dit_hi;
552     return result;
553 }
554 
555 /*
556  * Add a dict entry to dictionary "d".
557  * Returns FAIL when out of memory and when key already exists.
558  */
559     int
560 dict_add_dict(dict_T *d, char *key, dict_T *dict)
561 {
562     dictitem_T	*item;
563 
564     item = dictitem_alloc((char_u *)key);
565     if (item == NULL)
566 	return FAIL;
567     item->di_tv.v_type = VAR_DICT;
568     item->di_tv.vval.v_dict = dict;
569     ++dict->dv_refcount;
570     if (dict_add(d, item) == FAIL)
571     {
572 	dictitem_free(item);
573 	return FAIL;
574     }
575     return OK;
576 }
577 
578 /*
579  * Get the number of items in a Dictionary.
580  */
581     long
582 dict_len(dict_T *d)
583 {
584     if (d == NULL)
585 	return 0L;
586     return (long)d->dv_hashtab.ht_used;
587 }
588 
589 /*
590  * Find item "key[len]" in Dictionary "d".
591  * If "len" is negative use strlen(key).
592  * Returns NULL when not found.
593  */
594     dictitem_T *
595 dict_find(dict_T *d, char_u *key, int len)
596 {
597 #define AKEYLEN 200
598     char_u	buf[AKEYLEN];
599     char_u	*akey;
600     char_u	*tofree = NULL;
601     hashitem_T	*hi;
602 
603     if (d == NULL)
604 	return NULL;
605     if (len < 0)
606 	akey = key;
607     else if (len >= AKEYLEN)
608     {
609 	tofree = akey = vim_strnsave(key, len);
610 	if (akey == NULL)
611 	    return NULL;
612     }
613     else
614     {
615 	// Avoid a malloc/free by using buf[].
616 	vim_strncpy(buf, key, len);
617 	akey = buf;
618     }
619 
620     hi = hash_find(&d->dv_hashtab, akey);
621     vim_free(tofree);
622     if (HASHITEM_EMPTY(hi))
623 	return NULL;
624     return HI2DI(hi);
625 }
626 
627 /*
628  * Get a typval_T item from a dictionary and copy it into "rettv".
629  * Returns FAIL if the entry doesn't exist or out of memory.
630  */
631     int
632 dict_get_tv(dict_T *d, char_u *key, typval_T *rettv)
633 {
634     dictitem_T	*di;
635 
636     di = dict_find(d, key, -1);
637     if (di == NULL)
638 	return FAIL;
639     copy_tv(&di->di_tv, rettv);
640     return OK;
641 }
642 
643 /*
644  * Get a string item from a dictionary.
645  * When "save" is TRUE allocate memory for it.
646  * When FALSE a shared buffer is used, can only be used once!
647  * Returns NULL if the entry doesn't exist or out of memory.
648  */
649     char_u *
650 dict_get_string(dict_T *d, char_u *key, int save)
651 {
652     dictitem_T	*di;
653     char_u	*s;
654 
655     di = dict_find(d, key, -1);
656     if (di == NULL)
657 	return NULL;
658     s = tv_get_string(&di->di_tv);
659     if (save && s != NULL)
660 	s = vim_strsave(s);
661     return s;
662 }
663 
664 /*
665  * Get a number item from a dictionary.
666  * Returns 0 if the entry doesn't exist.
667  */
668     varnumber_T
669 dict_get_number(dict_T *d, char_u *key)
670 {
671     return dict_get_number_def(d, key, 0);
672 }
673 
674 /*
675  * Get a number item from a dictionary.
676  * Returns "def" if the entry doesn't exist.
677  */
678     varnumber_T
679 dict_get_number_def(dict_T *d, char_u *key, int def)
680 {
681     dictitem_T	*di;
682 
683     di = dict_find(d, key, -1);
684     if (di == NULL)
685 	return def;
686     return tv_get_number(&di->di_tv);
687 }
688 
689 /*
690  * Get a number item from a dictionary.
691  * Returns 0 if the entry doesn't exist.
692  * Give an error if the entry is not a number.
693  */
694     varnumber_T
695 dict_get_number_check(dict_T *d, char_u *key)
696 {
697     dictitem_T	*di;
698 
699     di = dict_find(d, key, -1);
700     if (di == NULL)
701 	return 0;
702     if (di->di_tv.v_type != VAR_NUMBER)
703     {
704 	semsg(_(e_invarg2), tv_get_string(&di->di_tv));
705 	return 0;
706     }
707     return tv_get_number(&di->di_tv);
708 }
709 
710 /*
711  * Get a bool item (number or true/false) from a dictionary.
712  * Returns "def" if the entry doesn't exist.
713  */
714     varnumber_T
715 dict_get_bool(dict_T *d, char_u *key, int def)
716 {
717     dictitem_T	*di;
718 
719     di = dict_find(d, key, -1);
720     if (di == NULL)
721 	return def;
722     return tv_get_bool(&di->di_tv);
723 }
724 
725 /*
726  * Return an allocated string with the string representation of a Dictionary.
727  * May return NULL.
728  */
729     char_u *
730 dict2string(typval_T *tv, int copyID, int restore_copyID)
731 {
732     garray_T	ga;
733     int		first = TRUE;
734     char_u	*tofree;
735     char_u	numbuf[NUMBUFLEN];
736     hashitem_T	*hi;
737     char_u	*s;
738     dict_T	*d;
739     int		todo;
740 
741     if ((d = tv->vval.v_dict) == NULL)
742 	return NULL;
743     ga_init2(&ga, (int)sizeof(char), 80);
744     ga_append(&ga, '{');
745 
746     todo = (int)d->dv_hashtab.ht_used;
747     for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
748     {
749 	if (!HASHITEM_EMPTY(hi))
750 	{
751 	    --todo;
752 
753 	    if (first)
754 		first = FALSE;
755 	    else
756 		ga_concat(&ga, (char_u *)", ");
757 
758 	    tofree = string_quote(hi->hi_key, FALSE);
759 	    if (tofree != NULL)
760 	    {
761 		ga_concat(&ga, tofree);
762 		vim_free(tofree);
763 	    }
764 	    ga_concat(&ga, (char_u *)": ");
765 	    s = echo_string_core(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID,
766 						 FALSE, restore_copyID, TRUE);
767 	    if (s != NULL)
768 		ga_concat(&ga, s);
769 	    vim_free(tofree);
770 	    if (s == NULL || did_echo_string_emsg)
771 		break;
772 	    line_breakcheck();
773 
774 	}
775     }
776     if (todo > 0)
777     {
778 	vim_free(ga.ga_data);
779 	return NULL;
780     }
781 
782     ga_append(&ga, '}');
783     ga_append(&ga, NUL);
784     return (char_u *)ga.ga_data;
785 }
786 
787 /*
788  * Advance over a literal key, including "-".  If the first character is not a
789  * literal key character then "key" is returned.
790  */
791     char_u *
792 skip_literal_key(char_u *key)
793 {
794     char_u *p;
795 
796     for (p = key; ASCII_ISALNUM(*p) || *p == '_' || *p == '-'; ++p)
797 	;
798     return p;
799 }
800 
801 /*
802  * Get the key for #{key: val} into "tv" and advance "arg".
803  * Return FAIL when there is no valid key.
804  */
805     static int
806 get_literal_key_tv(char_u **arg, typval_T *tv)
807 {
808     char_u *p = skip_literal_key(*arg);
809 
810     if (p == *arg)
811 	return FAIL;
812     tv->v_type = VAR_STRING;
813     tv->vval.v_string = vim_strnsave(*arg, p - *arg);
814 
815     *arg = p;
816     return OK;
817 }
818 
819 /*
820  * Get a literal key for a Vim9 dict:
821  * {"name": value},
822  * {'name': value},
823  * {name: value} use "name" as a literal key
824  * Return the key in allocated memory or NULL in the case of an error.
825  * "arg" is advanced to just after the key.
826  */
827     char_u *
828 get_literal_key(char_u **arg)
829 {
830     char_u	*key;
831     char_u	*end;
832     typval_T	rettv;
833 
834     if (**arg == '\'')
835     {
836 	if (eval_lit_string(arg, &rettv, TRUE) == FAIL)
837 	    return NULL;
838 	key = rettv.vval.v_string;
839     }
840     else if (**arg == '"')
841     {
842 	if (eval_string(arg, &rettv, TRUE) == FAIL)
843 	    return NULL;
844 	key = rettv.vval.v_string;
845     }
846     else
847     {
848 	end = skip_literal_key(*arg);
849 	if (end == *arg)
850 	{
851 	    semsg(_(e_invalid_key_str), *arg);
852 	    return NULL;
853 	}
854 	key = vim_strnsave(*arg, end - *arg);
855 	*arg = end;
856     }
857     return key;
858 }
859 
860 /*
861  * Allocate a variable for a Dictionary and fill it from "*arg".
862  * "*arg" points to the "{".
863  * "literal" is TRUE for #{key: val}
864  * Return OK or FAIL.  Returns NOTDONE for {expr}.
865  */
866     int
867 eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal)
868 {
869     int		evaluate = evalarg == NULL ? FALSE
870 					 : evalarg->eval_flags & EVAL_EVALUATE;
871     dict_T	*d = NULL;
872     typval_T	tvkey;
873     typval_T	tv;
874     char_u	*key = NULL;
875     dictitem_T	*item;
876     char_u	*start = skipwhite(*arg + 1);
877     char_u	buf[NUMBUFLEN];
878     int		vim9script = in_vim9script();
879     int		had_comma;
880 
881     /*
882      * First check if it's not a curly-braces thing: {expr}.
883      * Must do this without evaluating, otherwise a function may be called
884      * twice.  Unfortunately this means we need to call eval1() twice for the
885      * first item.
886      * But {} is an empty Dictionary.
887      */
888     if (!vim9script && *start != '}')
889     {
890 	if (eval1(&start, &tv, NULL) == FAIL)	// recursive!
891 	    return FAIL;
892 	if (*skipwhite(start) == '}')
893 	    return NOTDONE;
894     }
895 
896     if (evaluate)
897     {
898 	d = dict_alloc();
899 	if (d == NULL)
900 	    return FAIL;
901     }
902     tvkey.v_type = VAR_UNKNOWN;
903     tv.v_type = VAR_UNKNOWN;
904 
905     *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
906     while (**arg != '}' && **arg != NUL)
907     {
908 	int	has_bracket = vim9script && **arg == '[';
909 
910 	if (literal)
911 	{
912 	    if (get_literal_key_tv(arg, &tvkey) == FAIL)
913 		goto failret;
914 	}
915 	else if (vim9script && !has_bracket)
916 	{
917 	    tvkey.vval.v_string = get_literal_key(arg);
918 	    if (tvkey.vval.v_string == NULL)
919 		goto failret;
920 	    tvkey.v_type = VAR_STRING;
921 	}
922 	else
923 	{
924 	    if (has_bracket)
925 		*arg = skipwhite(*arg + 1);
926 	    if (eval1(arg, &tvkey, evalarg) == FAIL)	// recursive!
927 		goto failret;
928 	    if (has_bracket)
929 	    {
930 		*arg = skipwhite(*arg);
931 		if (**arg != ']')
932 		{
933 		    emsg(_(e_missing_matching_bracket_after_dict_key));
934 		    clear_tv(&tvkey);
935 		    return FAIL;
936 		}
937 		++*arg;
938 	    }
939 	}
940 
941 	// the colon should come right after the key, but this wasn't checked
942 	// previously, so only require it in Vim9 script.
943 	if (!vim9script)
944 	    *arg = skipwhite(*arg);
945 	if (**arg != ':')
946 	{
947 	    if (*skipwhite(*arg) == ':')
948 		semsg(_(e_no_white_space_allowed_before_str_str), ":", *arg);
949 	    else
950 		semsg(_(e_missing_dict_colon), *arg);
951 	    clear_tv(&tvkey);
952 	    goto failret;
953 	}
954 	if (evaluate)
955 	{
956 #ifdef FEAT_FLOAT
957 	    if (tvkey.v_type == VAR_FLOAT)
958 	    {
959 		tvkey.vval.v_string = typval_tostring(&tvkey, TRUE);
960 		tvkey.v_type = VAR_STRING;
961 	    }
962 #endif
963 	    key = tv_get_string_buf_chk(&tvkey, buf);
964 	    if (key == NULL)
965 	    {
966 		// "key" is NULL when tv_get_string_buf_chk() gave an errmsg
967 		clear_tv(&tvkey);
968 		goto failret;
969 	    }
970 	}
971 	if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1]))
972 	{
973 	    semsg(_(e_white_space_required_after_str_str), ":", *arg);
974 	    clear_tv(&tvkey);
975 	    goto failret;
976 	}
977 
978 	*arg = skipwhite_and_linebreak(*arg + 1, evalarg);
979 	if (eval1(arg, &tv, evalarg) == FAIL)	// recursive!
980 	{
981 	    if (evaluate)
982 		clear_tv(&tvkey);
983 	    goto failret;
984 	}
985 	if (evaluate)
986 	{
987 	    item = dict_find(d, key, -1);
988 	    if (item != NULL)
989 	    {
990 		semsg(_(e_duplicate_key), key);
991 		clear_tv(&tvkey);
992 		clear_tv(&tv);
993 		goto failret;
994 	    }
995 	    item = dictitem_alloc(key);
996 	    if (item != NULL)
997 	    {
998 		item->di_tv = tv;
999 		item->di_tv.v_lock = 0;
1000 		if (dict_add(d, item) == FAIL)
1001 		    dictitem_free(item);
1002 	    }
1003 	}
1004 	clear_tv(&tvkey);
1005 
1006 	// the comma should come right after the value, but this wasn't checked
1007 	// previously, so only require it in Vim9 script.
1008 	if (!vim9script)
1009 	    *arg = skipwhite(*arg);
1010 	had_comma = **arg == ',';
1011 	if (had_comma)
1012 	{
1013 	    if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1]))
1014 	    {
1015 		semsg(_(e_white_space_required_after_str_str), ",", *arg);
1016 		goto failret;
1017 	    }
1018 	    *arg = skipwhite(*arg + 1);
1019 	}
1020 
1021 	// the "}" can be on the next line
1022 	*arg = skipwhite_and_linebreak(*arg, evalarg);
1023 	if (**arg == '}')
1024 	    break;
1025 	if (!had_comma)
1026 	{
1027 	    if (**arg == ',')
1028 		semsg(_(e_no_white_space_allowed_before_str_str), ",", *arg);
1029 	    else
1030 		semsg(_(e_missing_dict_comma), *arg);
1031 	    goto failret;
1032 	}
1033     }
1034 
1035     if (**arg != '}')
1036     {
1037 	if (evalarg != NULL)
1038 	    semsg(_(e_missing_dict_end), *arg);
1039 failret:
1040 	if (d != NULL)
1041 	    dict_free(d);
1042 	return FAIL;
1043     }
1044 
1045     *arg = *arg + 1;
1046     if (evaluate)
1047 	rettv_dict_set(rettv, d);
1048 
1049     return OK;
1050 }
1051 
1052 /*
1053  * Go over all entries in "d2" and add them to "d1".
1054  * When "action" is "error" then a duplicate key is an error.
1055  * When "action" is "force" then a duplicate key is overwritten.
1056  * Otherwise duplicate keys are ignored ("action" is "keep").
1057  */
1058     void
1059 dict_extend(dict_T *d1, dict_T *d2, char_u *action)
1060 {
1061     dictitem_T	*di1;
1062     hashitem_T	*hi2;
1063     int		todo;
1064     char_u	*arg_errmsg = (char_u *)N_("extend() argument");
1065     type_T	*type;
1066 
1067     if (d1->dv_type != NULL && d1->dv_type->tt_member != NULL)
1068 	type = d1->dv_type->tt_member;
1069     else
1070 	type = NULL;
1071 
1072     todo = (int)d2->dv_hashtab.ht_used;
1073     for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2)
1074     {
1075 	if (!HASHITEM_EMPTY(hi2))
1076 	{
1077 	    --todo;
1078 	    di1 = dict_find(d1, hi2->hi_key, -1);
1079 	    if (d1->dv_scope != 0)
1080 	    {
1081 		// Disallow replacing a builtin function in l: and g:.
1082 		// Check the key to be valid when adding to any scope.
1083 		if (d1->dv_scope == VAR_DEF_SCOPE
1084 			&& HI2DI(hi2)->di_tv.v_type == VAR_FUNC
1085 			&& var_wrong_func_name(hi2->hi_key, di1 == NULL))
1086 		    break;
1087 		if (!valid_varname(hi2->hi_key, TRUE))
1088 		    break;
1089 	    }
1090 
1091 	    if (type != NULL
1092 		     && check_typval_arg_type(type, &HI2DI(hi2)->di_tv, 0)
1093 								       == FAIL)
1094 		break;
1095 
1096 	    if (di1 == NULL)
1097 	    {
1098 		di1 = dictitem_copy(HI2DI(hi2));
1099 		if (di1 != NULL && dict_add(d1, di1) == FAIL)
1100 		    dictitem_free(di1);
1101 	    }
1102 	    else if (*action == 'e')
1103 	    {
1104 		semsg(_("E737: Key already exists: %s"), hi2->hi_key);
1105 		break;
1106 	    }
1107 	    else if (*action == 'f' && HI2DI(hi2) != di1)
1108 	    {
1109 		if (value_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE)
1110 			|| var_check_ro(di1->di_flags, arg_errmsg, TRUE))
1111 		    break;
1112 		clear_tv(&di1->di_tv);
1113 		copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
1114 	    }
1115 	}
1116     }
1117 }
1118 
1119 /*
1120  * Return the dictitem that an entry in a hashtable points to.
1121  */
1122     dictitem_T *
1123 dict_lookup(hashitem_T *hi)
1124 {
1125     return HI2DI(hi);
1126 }
1127 
1128 /*
1129  * Return TRUE when two dictionaries have exactly the same key/values.
1130  */
1131     int
1132 dict_equal(
1133     dict_T	*d1,
1134     dict_T	*d2,
1135     int		ic,	    // ignore case for strings
1136     int		recursive)  // TRUE when used recursively
1137 {
1138     hashitem_T	*hi;
1139     dictitem_T	*item2;
1140     int		todo;
1141 
1142     if (d1 == d2)
1143 	return TRUE;
1144     if (dict_len(d1) != dict_len(d2))
1145 	return FALSE;
1146     if (dict_len(d1) == 0)
1147 	// empty and NULL dicts are considered equal
1148 	return TRUE;
1149     if (d1 == NULL || d2 == NULL)
1150 	return FALSE;
1151 
1152     todo = (int)d1->dv_hashtab.ht_used;
1153     for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi)
1154     {
1155 	if (!HASHITEM_EMPTY(hi))
1156 	{
1157 	    item2 = dict_find(d2, hi->hi_key, -1);
1158 	    if (item2 == NULL)
1159 		return FALSE;
1160 	    if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive))
1161 		return FALSE;
1162 	    --todo;
1163 	}
1164     }
1165     return TRUE;
1166 }
1167 
1168 /*
1169  * Turn a dict into a list:
1170  * "what" == 0: list of keys
1171  * "what" == 1: list of values
1172  * "what" == 2: list of items
1173  */
1174     static void
1175 dict_list(typval_T *argvars, typval_T *rettv, int what)
1176 {
1177     list_T	*l2;
1178     dictitem_T	*di;
1179     hashitem_T	*hi;
1180     listitem_T	*li;
1181     listitem_T	*li2;
1182     dict_T	*d;
1183     int		todo;
1184 
1185     if (argvars[0].v_type != VAR_DICT)
1186     {
1187 	emsg(_(e_dictreq));
1188 	return;
1189     }
1190     if ((d = argvars[0].vval.v_dict) == NULL)
1191 	return;
1192 
1193     if (rettv_list_alloc(rettv) == FAIL)
1194 	return;
1195 
1196     todo = (int)d->dv_hashtab.ht_used;
1197     for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
1198     {
1199 	if (!HASHITEM_EMPTY(hi))
1200 	{
1201 	    --todo;
1202 	    di = HI2DI(hi);
1203 
1204 	    li = listitem_alloc();
1205 	    if (li == NULL)
1206 		break;
1207 	    list_append(rettv->vval.v_list, li);
1208 
1209 	    if (what == 0)
1210 	    {
1211 		// keys()
1212 		li->li_tv.v_type = VAR_STRING;
1213 		li->li_tv.v_lock = 0;
1214 		li->li_tv.vval.v_string = vim_strsave(di->di_key);
1215 	    }
1216 	    else if (what == 1)
1217 	    {
1218 		// values()
1219 		copy_tv(&di->di_tv, &li->li_tv);
1220 	    }
1221 	    else
1222 	    {
1223 		// items()
1224 		l2 = list_alloc();
1225 		li->li_tv.v_type = VAR_LIST;
1226 		li->li_tv.v_lock = 0;
1227 		li->li_tv.vval.v_list = l2;
1228 		if (l2 == NULL)
1229 		    break;
1230 		++l2->lv_refcount;
1231 
1232 		li2 = listitem_alloc();
1233 		if (li2 == NULL)
1234 		    break;
1235 		list_append(l2, li2);
1236 		li2->li_tv.v_type = VAR_STRING;
1237 		li2->li_tv.v_lock = 0;
1238 		li2->li_tv.vval.v_string = vim_strsave(di->di_key);
1239 
1240 		li2 = listitem_alloc();
1241 		if (li2 == NULL)
1242 		    break;
1243 		list_append(l2, li2);
1244 		copy_tv(&di->di_tv, &li2->li_tv);
1245 	    }
1246 	}
1247     }
1248 }
1249 
1250 /*
1251  * "items(dict)" function
1252  */
1253     void
1254 f_items(typval_T *argvars, typval_T *rettv)
1255 {
1256     dict_list(argvars, rettv, 2);
1257 }
1258 
1259 /*
1260  * "keys()" function
1261  */
1262     void
1263 f_keys(typval_T *argvars, typval_T *rettv)
1264 {
1265     dict_list(argvars, rettv, 0);
1266 }
1267 
1268 /*
1269  * "values(dict)" function
1270  */
1271     void
1272 f_values(typval_T *argvars, typval_T *rettv)
1273 {
1274     dict_list(argvars, rettv, 1);
1275 }
1276 
1277 /*
1278  * Make each item in the dict readonly (not the value of the item).
1279  */
1280     void
1281 dict_set_items_ro(dict_T *di)
1282 {
1283     int		todo = (int)di->dv_hashtab.ht_used;
1284     hashitem_T	*hi;
1285 
1286     // Set readonly
1287     for (hi = di->dv_hashtab.ht_array; todo > 0 ; ++hi)
1288     {
1289 	if (HASHITEM_EMPTY(hi))
1290 	    continue;
1291 	--todo;
1292 	HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
1293     }
1294 }
1295 
1296 /*
1297  * "has_key()" function
1298  */
1299     void
1300 f_has_key(typval_T *argvars, typval_T *rettv)
1301 {
1302     if (argvars[0].v_type != VAR_DICT)
1303     {
1304 	emsg(_(e_dictreq));
1305 	return;
1306     }
1307     if (argvars[0].vval.v_dict == NULL)
1308 	return;
1309 
1310     rettv->vval.v_number = dict_find(argvars[0].vval.v_dict,
1311 				      tv_get_string(&argvars[1]), -1) != NULL;
1312 }
1313 
1314 /*
1315  * "remove({dict})" function
1316  */
1317     void
1318 dict_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
1319 {
1320     dict_T	*d;
1321     char_u	*key;
1322     dictitem_T	*di;
1323 
1324     if (argvars[2].v_type != VAR_UNKNOWN)
1325 	semsg(_(e_toomanyarg), "remove()");
1326     else if ((d = argvars[0].vval.v_dict) != NULL
1327 	    && !value_check_lock(d->dv_lock, arg_errmsg, TRUE))
1328     {
1329 	key = tv_get_string_chk(&argvars[1]);
1330 	if (key != NULL)
1331 	{
1332 	    di = dict_find(d, key, -1);
1333 	    if (di == NULL)
1334 		semsg(_(e_dictkey), key);
1335 	    else if (!var_check_fixed(di->di_flags, arg_errmsg, TRUE)
1336 			&& !var_check_ro(di->di_flags, arg_errmsg, TRUE))
1337 	    {
1338 		*rettv = di->di_tv;
1339 		init_tv(&di->di_tv);
1340 		dictitem_remove(d, di);
1341 	    }
1342 	}
1343     }
1344 }
1345 
1346 #endif // defined(FEAT_EVAL)
1347