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