xref: /vim-8.2.3635/src/list.c (revision bc93cebb)
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  * list.c: List support and container (List, Dict, Blob) functions.
12  */
13 
14 #include "vim.h"
15 
16 #if defined(FEAT_EVAL) || defined(PROTO)
17 
18 static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
19 
20 // List heads for garbage collection.
21 static list_T		*first_list = NULL;	// list of all lists
22 
23 /*
24  * Add a watcher to a list.
25  */
26     void
27 list_add_watch(list_T *l, listwatch_T *lw)
28 {
29     lw->lw_next = l->lv_watch;
30     l->lv_watch = lw;
31 }
32 
33 /*
34  * Remove a watcher from a list.
35  * No warning when it isn't found...
36  */
37     void
38 list_rem_watch(list_T *l, listwatch_T *lwrem)
39 {
40     listwatch_T	*lw, **lwp;
41 
42     lwp = &l->lv_watch;
43     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
44     {
45 	if (lw == lwrem)
46 	{
47 	    *lwp = lw->lw_next;
48 	    break;
49 	}
50 	lwp = &lw->lw_next;
51     }
52 }
53 
54 /*
55  * Just before removing an item from a list: advance watchers to the next
56  * item.
57  */
58     static void
59 list_fix_watch(list_T *l, listitem_T *item)
60 {
61     listwatch_T	*lw;
62 
63     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
64 	if (lw->lw_item == item)
65 	    lw->lw_item = item->li_next;
66 }
67 
68     static void
69 list_init(list_T *l)
70 {
71     // Prepend the list to the list of lists for garbage collection.
72     if (first_list != NULL)
73 	first_list->lv_used_prev = l;
74     l->lv_used_prev = NULL;
75     l->lv_used_next = first_list;
76     first_list = l;
77 }
78 
79 /*
80  * Allocate an empty header for a list.
81  * Caller should take care of the reference count.
82  */
83     list_T *
84 list_alloc(void)
85 {
86     list_T  *l;
87 
88     l = ALLOC_CLEAR_ONE(list_T);
89     if (l != NULL)
90 	list_init(l);
91     return l;
92 }
93 
94 /*
95  * list_alloc() with an ID for alloc_fail().
96  */
97     list_T *
98 list_alloc_id(alloc_id_T id UNUSED)
99 {
100 #ifdef FEAT_EVAL
101     if (alloc_fail_id == id && alloc_does_fail(sizeof(list_T)))
102 	return NULL;
103 #endif
104     return (list_alloc());
105 }
106 
107 /*
108  * Allocate space for a list, plus "count" items.
109  * Next list_set_item() must be called for each item.
110  */
111     list_T *
112 list_alloc_with_items(int count)
113 {
114     list_T	*l;
115 
116     l = (list_T *)alloc_clear(sizeof(list_T) + count * sizeof(listitem_T));
117     if (l != NULL)
118     {
119 	list_init(l);
120 
121 	if (count > 0)
122 	{
123 	    listitem_T	*li = (listitem_T *)(l + 1);
124 	    int		i;
125 
126 	    l->lv_len = count;
127 	    l->lv_with_items = count;
128 	    l->lv_first = li;
129 	    l->lv_u.mat.lv_last = li + count - 1;
130 	    for (i = 0; i < count; ++i)
131 	    {
132 		if (i == 0)
133 		    li->li_prev = NULL;
134 		else
135 		    li->li_prev = li - 1;
136 		if (i == count - 1)
137 		    li->li_next = NULL;
138 		else
139 		    li->li_next = li + 1;
140 		++li;
141 	    }
142 	}
143     }
144     return l;
145 }
146 
147 /*
148  * Set item "idx" for a list previously allocated with list_alloc_with_items().
149  * The contents of "tv" is moved into the list item.
150  * Each item must be set exactly once.
151  */
152     void
153 list_set_item(list_T *l, int idx, typval_T *tv)
154 {
155     listitem_T	*li = (listitem_T *)(l + 1) + idx;
156 
157     li->li_tv = *tv;
158 }
159 
160 /*
161  * Allocate an empty list for a return value, with reference count set.
162  * Returns OK or FAIL.
163  */
164     int
165 rettv_list_alloc(typval_T *rettv)
166 {
167     list_T	*l = list_alloc();
168 
169     if (l == NULL)
170 	return FAIL;
171 
172     rettv->v_lock = 0;
173     rettv_list_set(rettv, l);
174     return OK;
175 }
176 
177 /*
178  * Same as rettv_list_alloc() but uses an allocation id for testing.
179  */
180     int
181 rettv_list_alloc_id(typval_T *rettv, alloc_id_T id UNUSED)
182 {
183 #ifdef FEAT_EVAL
184     if (alloc_fail_id == id && alloc_does_fail(sizeof(list_T)))
185 	return FAIL;
186 #endif
187     return rettv_list_alloc(rettv);
188 }
189 
190 
191 /*
192  * Set a list as the return value.  Increments the reference count.
193  */
194     void
195 rettv_list_set(typval_T *rettv, list_T *l)
196 {
197     rettv->v_type = VAR_LIST;
198     rettv->vval.v_list = l;
199     if (l != NULL)
200 	++l->lv_refcount;
201 }
202 
203 /*
204  * Unreference a list: decrement the reference count and free it when it
205  * becomes zero.
206  */
207     void
208 list_unref(list_T *l)
209 {
210     if (l != NULL && --l->lv_refcount <= 0)
211 	list_free(l);
212 }
213 
214 /*
215  * Free a list, including all non-container items it points to.
216  * Ignores the reference count.
217  */
218     static void
219 list_free_contents(list_T *l)
220 {
221     listitem_T *item;
222 
223     if (l->lv_first != &range_list_item)
224 	for (item = l->lv_first; item != NULL; item = l->lv_first)
225 	{
226 	    // Remove the item before deleting it.
227 	    l->lv_first = item->li_next;
228 	    clear_tv(&item->li_tv);
229 	    list_free_item(l, item);
230 	}
231 }
232 
233 /*
234  * Go through the list of lists and free items without the copyID.
235  * But don't free a list that has a watcher (used in a for loop), these
236  * are not referenced anywhere.
237  */
238     int
239 list_free_nonref(int copyID)
240 {
241     list_T	*ll;
242     int		did_free = FALSE;
243 
244     for (ll = first_list; ll != NULL; ll = ll->lv_used_next)
245 	if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
246 						      && ll->lv_watch == NULL)
247 	{
248 	    // Free the List and ordinary items it contains, but don't recurse
249 	    // into Lists and Dictionaries, they will be in the list of dicts
250 	    // or list of lists.
251 	    list_free_contents(ll);
252 	    did_free = TRUE;
253 	}
254     return did_free;
255 }
256 
257     static void
258 list_free_list(list_T  *l)
259 {
260     // Remove the list from the list of lists for garbage collection.
261     if (l->lv_used_prev == NULL)
262 	first_list = l->lv_used_next;
263     else
264 	l->lv_used_prev->lv_used_next = l->lv_used_next;
265     if (l->lv_used_next != NULL)
266 	l->lv_used_next->lv_used_prev = l->lv_used_prev;
267 
268     vim_free(l);
269 }
270 
271     void
272 list_free_items(int copyID)
273 {
274     list_T	*ll, *ll_next;
275 
276     for (ll = first_list; ll != NULL; ll = ll_next)
277     {
278 	ll_next = ll->lv_used_next;
279 	if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
280 						      && ll->lv_watch == NULL)
281 	{
282 	    // Free the List and ordinary items it contains, but don't recurse
283 	    // into Lists and Dictionaries, they will be in the list of dicts
284 	    // or list of lists.
285 	    list_free_list(ll);
286 	}
287     }
288 }
289 
290     void
291 list_free(list_T *l)
292 {
293     if (!in_free_unref_items)
294     {
295 	list_free_contents(l);
296 	list_free_list(l);
297     }
298 }
299 
300 /*
301  * Allocate a list item.
302  * It is not initialized, don't forget to set v_lock.
303  */
304     listitem_T *
305 listitem_alloc(void)
306 {
307     return ALLOC_ONE(listitem_T);
308 }
309 
310 /*
311  * Free a list item, unless it was allocated together with the list itself.
312  * Does not clear the value.  Does not notify watchers.
313  */
314     void
315 list_free_item(list_T *l, listitem_T *item)
316 {
317     if (l->lv_with_items == 0 || item < (listitem_T *)l
318 			   || item >= (listitem_T *)(l + 1) + l->lv_with_items)
319 	vim_free(item);
320 }
321 
322 /*
323  * Free a list item, unless it was allocated together with the list itself.
324  * Also clears the value.  Does not notify watchers.
325  */
326     void
327 listitem_free(list_T *l, listitem_T *item)
328 {
329     clear_tv(&item->li_tv);
330     list_free_item(l, item);
331 }
332 
333 /*
334  * Remove a list item from a List and free it.  Also clears the value.
335  */
336     void
337 listitem_remove(list_T *l, listitem_T *item)
338 {
339     vimlist_remove(l, item, item);
340     listitem_free(l, item);
341 }
342 
343 /*
344  * Get the number of items in a list.
345  */
346     long
347 list_len(list_T *l)
348 {
349     if (l == NULL)
350 	return 0L;
351     return l->lv_len;
352 }
353 
354 /*
355  * Return TRUE when two lists have exactly the same values.
356  */
357     int
358 list_equal(
359     list_T	*l1,
360     list_T	*l2,
361     int		ic,	// ignore case for strings
362     int		recursive)  // TRUE when used recursively
363 {
364     listitem_T	*item1, *item2;
365 
366     if (l1 == NULL || l2 == NULL)
367 	return FALSE;
368     if (l1 == l2)
369 	return TRUE;
370     if (list_len(l1) != list_len(l2))
371 	return FALSE;
372 
373     range_list_materialize(l1);
374     range_list_materialize(l2);
375 
376     for (item1 = l1->lv_first, item2 = l2->lv_first;
377 	    item1 != NULL && item2 != NULL;
378 			       item1 = item1->li_next, item2 = item2->li_next)
379 	if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
380 	    return FALSE;
381     return item1 == NULL && item2 == NULL;
382 }
383 
384 /*
385  * Locate item with index "n" in list "l" and return it.
386  * A negative index is counted from the end; -1 is the last item.
387  * Returns NULL when "n" is out of range.
388  */
389     listitem_T *
390 list_find(list_T *l, long n)
391 {
392     listitem_T	*item;
393     long	idx;
394 
395     if (l == NULL)
396 	return NULL;
397 
398     // Negative index is relative to the end.
399     if (n < 0)
400 	n = l->lv_len + n;
401 
402     // Check for index out of range.
403     if (n < 0 || n >= l->lv_len)
404 	return NULL;
405 
406     range_list_materialize(l);
407 
408     // When there is a cached index may start search from there.
409     if (l->lv_u.mat.lv_idx_item != NULL)
410     {
411 	if (n < l->lv_u.mat.lv_idx / 2)
412 	{
413 	    // closest to the start of the list
414 	    item = l->lv_first;
415 	    idx = 0;
416 	}
417 	else if (n > (l->lv_u.mat.lv_idx + l->lv_len) / 2)
418 	{
419 	    // closest to the end of the list
420 	    item = l->lv_u.mat.lv_last;
421 	    idx = l->lv_len - 1;
422 	}
423 	else
424 	{
425 	    // closest to the cached index
426 	    item = l->lv_u.mat.lv_idx_item;
427 	    idx = l->lv_u.mat.lv_idx;
428 	}
429     }
430     else
431     {
432 	if (n < l->lv_len / 2)
433 	{
434 	    // closest to the start of the list
435 	    item = l->lv_first;
436 	    idx = 0;
437 	}
438 	else
439 	{
440 	    // closest to the end of the list
441 	    item = l->lv_u.mat.lv_last;
442 	    idx = l->lv_len - 1;
443 	}
444     }
445 
446     while (n > idx)
447     {
448 	// search forward
449 	item = item->li_next;
450 	++idx;
451     }
452     while (n < idx)
453     {
454 	// search backward
455 	item = item->li_prev;
456 	--idx;
457     }
458 
459     // cache the used index
460     l->lv_u.mat.lv_idx = idx;
461     l->lv_u.mat.lv_idx_item = item;
462 
463     return item;
464 }
465 
466 /*
467  * Get list item "l[idx]" as a number.
468  */
469     long
470 list_find_nr(
471     list_T	*l,
472     long	idx,
473     int		*errorp)	// set to TRUE when something wrong
474 {
475     listitem_T	*li;
476 
477     if (l != NULL && l->lv_first == &range_list_item)
478     {
479 	long	    n = idx;
480 
481 	// not materialized range() list: compute the value.
482 	// Negative index is relative to the end.
483 	if (n < 0)
484 	    n = l->lv_len + n;
485 
486 	// Check for index out of range.
487 	if (n < 0 || n >= l->lv_len)
488 	{
489 	    if (errorp != NULL)
490 		*errorp = TRUE;
491 	    return -1L;
492 	}
493 
494 	return l->lv_u.nonmat.lv_start + n * l->lv_u.nonmat.lv_stride;
495     }
496 
497     li = list_find(l, idx);
498     if (li == NULL)
499     {
500 	if (errorp != NULL)
501 	    *errorp = TRUE;
502 	return -1L;
503     }
504     return (long)tv_get_number_chk(&li->li_tv, errorp);
505 }
506 
507 /*
508  * Get list item "l[idx - 1]" as a string.  Returns NULL for failure.
509  */
510     char_u *
511 list_find_str(list_T *l, long idx)
512 {
513     listitem_T	*li;
514 
515     li = list_find(l, idx - 1);
516     if (li == NULL)
517     {
518 	semsg(_(e_listidx), idx);
519 	return NULL;
520     }
521     return tv_get_string(&li->li_tv);
522 }
523 
524 /*
525  * Locate "item" list "l" and return its index.
526  * Returns -1 when "item" is not in the list.
527  */
528     long
529 list_idx_of_item(list_T *l, listitem_T *item)
530 {
531     long	idx = 0;
532     listitem_T	*li;
533 
534     if (l == NULL)
535 	return -1;
536     range_list_materialize(l);
537     idx = 0;
538     for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
539 	++idx;
540     if (li == NULL)
541 	return -1;
542     return idx;
543 }
544 
545 /*
546  * Append item "item" to the end of list "l".
547  */
548     void
549 list_append(list_T *l, listitem_T *item)
550 {
551     range_list_materialize(l);
552     if (l->lv_u.mat.lv_last == NULL)
553     {
554 	// empty list
555 	l->lv_first = item;
556 	l->lv_u.mat.lv_last = item;
557 	item->li_prev = NULL;
558     }
559     else
560     {
561 	l->lv_u.mat.lv_last->li_next = item;
562 	item->li_prev = l->lv_u.mat.lv_last;
563 	l->lv_u.mat.lv_last = item;
564     }
565     ++l->lv_len;
566     item->li_next = NULL;
567 }
568 
569 /*
570  * Append typval_T "tv" to the end of list "l".  "tv" is copied.
571  * Return FAIL when out of memory.
572  */
573     int
574 list_append_tv(list_T *l, typval_T *tv)
575 {
576     listitem_T	*li = listitem_alloc();
577 
578     if (li == NULL)
579 	return FAIL;
580     copy_tv(tv, &li->li_tv);
581     list_append(l, li);
582     return OK;
583 }
584 
585 /*
586  * As list_append_tv() but move the value instead of copying it.
587  * Return FAIL when out of memory.
588  */
589     int
590 list_append_tv_move(list_T *l, typval_T *tv)
591 {
592     listitem_T	*li = listitem_alloc();
593 
594     if (li == NULL)
595 	return FAIL;
596     li->li_tv = *tv;
597     list_append(l, li);
598     return OK;
599 }
600 
601 /*
602  * Add a dictionary to a list.  Used by getqflist().
603  * Return FAIL when out of memory.
604  */
605     int
606 list_append_dict(list_T *list, dict_T *dict)
607 {
608     listitem_T	*li = listitem_alloc();
609 
610     if (li == NULL)
611 	return FAIL;
612     li->li_tv.v_type = VAR_DICT;
613     li->li_tv.v_lock = 0;
614     li->li_tv.vval.v_dict = dict;
615     list_append(list, li);
616     ++dict->dv_refcount;
617     return OK;
618 }
619 
620 /*
621  * Append list2 to list1.
622  * Return FAIL when out of memory.
623  */
624     int
625 list_append_list(list_T *list1, list_T *list2)
626 {
627     listitem_T	*li = listitem_alloc();
628 
629     if (li == NULL)
630 	return FAIL;
631     li->li_tv.v_type = VAR_LIST;
632     li->li_tv.v_lock = 0;
633     li->li_tv.vval.v_list = list2;
634     list_append(list1, li);
635     ++list2->lv_refcount;
636     return OK;
637 }
638 
639 /*
640  * Make a copy of "str" and append it as an item to list "l".
641  * When "len" >= 0 use "str[len]".
642  * Returns FAIL when out of memory.
643  */
644     int
645 list_append_string(list_T *l, char_u *str, int len)
646 {
647     listitem_T *li = listitem_alloc();
648 
649     if (li == NULL)
650 	return FAIL;
651     list_append(l, li);
652     li->li_tv.v_type = VAR_STRING;
653     li->li_tv.v_lock = 0;
654     if (str == NULL)
655 	li->li_tv.vval.v_string = NULL;
656     else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len)
657 						 : vim_strsave(str))) == NULL)
658 	return FAIL;
659     return OK;
660 }
661 
662 /*
663  * Append "n" to list "l".
664  * Returns FAIL when out of memory.
665  */
666     int
667 list_append_number(list_T *l, varnumber_T n)
668 {
669     listitem_T	*li;
670 
671     li = listitem_alloc();
672     if (li == NULL)
673 	return FAIL;
674     li->li_tv.v_type = VAR_NUMBER;
675     li->li_tv.v_lock = 0;
676     li->li_tv.vval.v_number = n;
677     list_append(l, li);
678     return OK;
679 }
680 
681 /*
682  * Insert typval_T "tv" in list "l" before "item".
683  * If "item" is NULL append at the end.
684  * Return FAIL when out of memory.
685  */
686     int
687 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
688 {
689     listitem_T	*ni = listitem_alloc();
690 
691     if (ni == NULL)
692 	return FAIL;
693     copy_tv(tv, &ni->li_tv);
694     list_insert(l, ni, item);
695     return OK;
696 }
697 
698     void
699 list_insert(list_T *l, listitem_T *ni, listitem_T *item)
700 {
701     range_list_materialize(l);
702     if (item == NULL)
703 	// Append new item at end of list.
704 	list_append(l, ni);
705     else
706     {
707 	// Insert new item before existing item.
708 	ni->li_prev = item->li_prev;
709 	ni->li_next = item;
710 	if (item->li_prev == NULL)
711 	{
712 	    l->lv_first = ni;
713 	    ++l->lv_u.mat.lv_idx;
714 	}
715 	else
716 	{
717 	    item->li_prev->li_next = ni;
718 	    l->lv_u.mat.lv_idx_item = NULL;
719 	}
720 	item->li_prev = ni;
721 	++l->lv_len;
722     }
723 }
724 
725 /*
726  * Extend "l1" with "l2".
727  * If "bef" is NULL append at the end, otherwise insert before this item.
728  * Returns FAIL when out of memory.
729  */
730     int
731 list_extend(list_T *l1, list_T *l2, listitem_T *bef)
732 {
733     listitem_T	*item;
734     int		todo = l2->lv_len;
735 
736     range_list_materialize(l1);
737     range_list_materialize(l2);
738 
739     // We also quit the loop when we have inserted the original item count of
740     // the list, avoid a hang when we extend a list with itself.
741     for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next)
742 	if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
743 	    return FAIL;
744     return OK;
745 }
746 
747 /*
748  * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
749  * Return FAIL when out of memory.
750  */
751     int
752 list_concat(list_T *l1, list_T *l2, typval_T *tv)
753 {
754     list_T	*l;
755 
756     if (l1 == NULL || l2 == NULL)
757 	return FAIL;
758 
759     // make a copy of the first list.
760     l = list_copy(l1, FALSE, 0);
761     if (l == NULL)
762 	return FAIL;
763     tv->v_type = VAR_LIST;
764     tv->vval.v_list = l;
765 
766     // append all items from the second list
767     return list_extend(l, l2, NULL);
768 }
769 
770 /*
771  * Make a copy of list "orig".  Shallow if "deep" is FALSE.
772  * The refcount of the new list is set to 1.
773  * See item_copy() for "copyID".
774  * Returns NULL when out of memory.
775  */
776     list_T *
777 list_copy(list_T *orig, int deep, int copyID)
778 {
779     list_T	*copy;
780     listitem_T	*item;
781     listitem_T	*ni;
782 
783     if (orig == NULL)
784 	return NULL;
785 
786     copy = list_alloc();
787     if (copy != NULL)
788     {
789 	if (copyID != 0)
790 	{
791 	    // Do this before adding the items, because one of the items may
792 	    // refer back to this list.
793 	    orig->lv_copyID = copyID;
794 	    orig->lv_copylist = copy;
795 	}
796 	range_list_materialize(orig);
797 	for (item = orig->lv_first; item != NULL && !got_int;
798 							 item = item->li_next)
799 	{
800 	    ni = listitem_alloc();
801 	    if (ni == NULL)
802 		break;
803 	    if (deep)
804 	    {
805 		if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL)
806 		{
807 		    vim_free(ni);
808 		    break;
809 		}
810 	    }
811 	    else
812 		copy_tv(&item->li_tv, &ni->li_tv);
813 	    list_append(copy, ni);
814 	}
815 	++copy->lv_refcount;
816 	if (item != NULL)
817 	{
818 	    list_unref(copy);
819 	    copy = NULL;
820 	}
821     }
822 
823     return copy;
824 }
825 
826 /*
827  * Remove items "item" to "item2" from list "l".
828  * Does not free the listitem or the value!
829  * This used to be called list_remove, but that conflicts with a Sun header
830  * file.
831  */
832     void
833 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
834 {
835     listitem_T	*ip;
836 
837     range_list_materialize(l);
838 
839     // notify watchers
840     for (ip = item; ip != NULL; ip = ip->li_next)
841     {
842 	--l->lv_len;
843 	list_fix_watch(l, ip);
844 	if (ip == item2)
845 	    break;
846     }
847 
848     if (item2->li_next == NULL)
849 	l->lv_u.mat.lv_last = item->li_prev;
850     else
851 	item2->li_next->li_prev = item->li_prev;
852     if (item->li_prev == NULL)
853 	l->lv_first = item2->li_next;
854     else
855 	item->li_prev->li_next = item2->li_next;
856     l->lv_u.mat.lv_idx_item = NULL;
857 }
858 
859 /*
860  * Return an allocated string with the string representation of a list.
861  * May return NULL.
862  */
863     char_u *
864 list2string(typval_T *tv, int copyID, int restore_copyID)
865 {
866     garray_T	ga;
867 
868     if (tv->vval.v_list == NULL)
869 	return NULL;
870     ga_init2(&ga, (int)sizeof(char), 80);
871     ga_append(&ga, '[');
872     range_list_materialize(tv->vval.v_list);
873     if (list_join(&ga, tv->vval.v_list, (char_u *)", ",
874 				       FALSE, restore_copyID, copyID) == FAIL)
875     {
876 	vim_free(ga.ga_data);
877 	return NULL;
878     }
879     ga_append(&ga, ']');
880     ga_append(&ga, NUL);
881     return (char_u *)ga.ga_data;
882 }
883 
884 typedef struct join_S {
885     char_u	*s;
886     char_u	*tofree;
887 } join_T;
888 
889     static int
890 list_join_inner(
891     garray_T	*gap,		// to store the result in
892     list_T	*l,
893     char_u	*sep,
894     int		echo_style,
895     int		restore_copyID,
896     int		copyID,
897     garray_T	*join_gap)	// to keep each list item string
898 {
899     int		i;
900     join_T	*p;
901     int		len;
902     int		sumlen = 0;
903     int		first = TRUE;
904     char_u	*tofree;
905     char_u	numbuf[NUMBUFLEN];
906     listitem_T	*item;
907     char_u	*s;
908 
909     // Stringify each item in the list.
910     range_list_materialize(l);
911     for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
912     {
913 	s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
914 				      echo_style, restore_copyID, !echo_style);
915 	if (s == NULL)
916 	    return FAIL;
917 
918 	len = (int)STRLEN(s);
919 	sumlen += len;
920 
921 	(void)ga_grow(join_gap, 1);
922 	p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
923 	if (tofree != NULL || s != numbuf)
924 	{
925 	    p->s = s;
926 	    p->tofree = tofree;
927 	}
928 	else
929 	{
930 	    p->s = vim_strnsave(s, len);
931 	    p->tofree = p->s;
932 	}
933 
934 	line_breakcheck();
935 	if (did_echo_string_emsg)  // recursion error, bail out
936 	    break;
937     }
938 
939     // Allocate result buffer with its total size, avoid re-allocation and
940     // multiple copy operations.  Add 2 for a tailing ']' and NUL.
941     if (join_gap->ga_len >= 2)
942 	sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
943     if (ga_grow(gap, sumlen + 2) == FAIL)
944 	return FAIL;
945 
946     for (i = 0; i < join_gap->ga_len && !got_int; ++i)
947     {
948 	if (first)
949 	    first = FALSE;
950 	else
951 	    ga_concat(gap, sep);
952 	p = ((join_T *)join_gap->ga_data) + i;
953 
954 	if (p->s != NULL)
955 	    ga_concat(gap, p->s);
956 	line_breakcheck();
957     }
958 
959     return OK;
960 }
961 
962 /*
963  * Join list "l" into a string in "*gap", using separator "sep".
964  * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
965  * Return FAIL or OK.
966  */
967     int
968 list_join(
969     garray_T	*gap,
970     list_T	*l,
971     char_u	*sep,
972     int		echo_style,
973     int		restore_copyID,
974     int		copyID)
975 {
976     garray_T	join_ga;
977     int		retval;
978     join_T	*p;
979     int		i;
980 
981     if (l->lv_len < 1)
982 	return OK; // nothing to do
983     ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
984     retval = list_join_inner(gap, l, sep, echo_style, restore_copyID,
985 							    copyID, &join_ga);
986 
987     // Dispose each item in join_ga.
988     if (join_ga.ga_data != NULL)
989     {
990 	p = (join_T *)join_ga.ga_data;
991 	for (i = 0; i < join_ga.ga_len; ++i)
992 	{
993 	    vim_free(p->tofree);
994 	    ++p;
995 	}
996 	ga_clear(&join_ga);
997     }
998 
999     return retval;
1000 }
1001 
1002 /*
1003  * "join()" function
1004  */
1005     void
1006 f_join(typval_T *argvars, typval_T *rettv)
1007 {
1008     garray_T	ga;
1009     char_u	*sep;
1010 
1011     if (argvars[0].v_type != VAR_LIST)
1012     {
1013 	emsg(_(e_listreq));
1014 	return;
1015     }
1016     if (argvars[0].vval.v_list == NULL)
1017 	return;
1018     if (argvars[1].v_type == VAR_UNKNOWN)
1019 	sep = (char_u *)" ";
1020     else
1021 	sep = tv_get_string_chk(&argvars[1]);
1022 
1023     rettv->v_type = VAR_STRING;
1024 
1025     if (sep != NULL)
1026     {
1027 	ga_init2(&ga, (int)sizeof(char), 80);
1028 	list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0);
1029 	ga_append(&ga, NUL);
1030 	rettv->vval.v_string = (char_u *)ga.ga_data;
1031     }
1032     else
1033 	rettv->vval.v_string = NULL;
1034 }
1035 
1036 /*
1037  * Allocate a variable for a List and fill it from "*arg".
1038  * Return OK or FAIL.
1039  */
1040     int
1041 get_list_tv(char_u **arg, typval_T *rettv, int evaluate, int do_error)
1042 {
1043     list_T	*l = NULL;
1044     typval_T	tv;
1045     listitem_T	*item;
1046 
1047     if (evaluate)
1048     {
1049 	l = list_alloc();
1050 	if (l == NULL)
1051 	    return FAIL;
1052     }
1053 
1054     *arg = skipwhite(*arg + 1);
1055     while (**arg != ']' && **arg != NUL)
1056     {
1057 	if (eval1(arg, &tv, evaluate) == FAIL)	// recursive!
1058 	    goto failret;
1059 	if (evaluate)
1060 	{
1061 	    item = listitem_alloc();
1062 	    if (item != NULL)
1063 	    {
1064 		item->li_tv = tv;
1065 		item->li_tv.v_lock = 0;
1066 		list_append(l, item);
1067 	    }
1068 	    else
1069 		clear_tv(&tv);
1070 	}
1071 
1072 	if (**arg == ']')
1073 	    break;
1074 	if (**arg != ',')
1075 	{
1076 	    if (do_error)
1077 		semsg(_("E696: Missing comma in List: %s"), *arg);
1078 	    goto failret;
1079 	}
1080 	*arg = skipwhite(*arg + 1);
1081     }
1082 
1083     if (**arg != ']')
1084     {
1085 	if (do_error)
1086 	    semsg(_("E697: Missing end of List ']': %s"), *arg);
1087 failret:
1088 	if (evaluate)
1089 	    list_free(l);
1090 	return FAIL;
1091     }
1092 
1093     *arg = skipwhite(*arg + 1);
1094     if (evaluate)
1095 	rettv_list_set(rettv, l);
1096 
1097     return OK;
1098 }
1099 
1100 /*
1101  * Write "list" of strings to file "fd".
1102  */
1103     int
1104 write_list(FILE *fd, list_T *list, int binary)
1105 {
1106     listitem_T	*li;
1107     int		c;
1108     int		ret = OK;
1109     char_u	*s;
1110 
1111     range_list_materialize(list);
1112     for (li = list->lv_first; li != NULL; li = li->li_next)
1113     {
1114 	for (s = tv_get_string(&li->li_tv); *s != NUL; ++s)
1115 	{
1116 	    if (*s == '\n')
1117 		c = putc(NUL, fd);
1118 	    else
1119 		c = putc(*s, fd);
1120 	    if (c == EOF)
1121 	    {
1122 		ret = FAIL;
1123 		break;
1124 	    }
1125 	}
1126 	if (!binary || li->li_next != NULL)
1127 	    if (putc('\n', fd) == EOF)
1128 	    {
1129 		ret = FAIL;
1130 		break;
1131 	    }
1132 	if (ret == FAIL)
1133 	{
1134 	    emsg(_(e_write));
1135 	    break;
1136 	}
1137     }
1138     return ret;
1139 }
1140 
1141 /*
1142  * Initialize a static list with 10 items.
1143  */
1144     void
1145 init_static_list(staticList10_T *sl)
1146 {
1147     list_T  *l = &sl->sl_list;
1148     int	    i;
1149 
1150     memset(sl, 0, sizeof(staticList10_T));
1151     l->lv_first = &sl->sl_items[0];
1152     l->lv_u.mat.lv_last = &sl->sl_items[9];
1153     l->lv_refcount = DO_NOT_FREE_CNT;
1154     l->lv_lock = VAR_FIXED;
1155     sl->sl_list.lv_len = 10;
1156 
1157     for (i = 0; i < 10; ++i)
1158     {
1159 	listitem_T *li = &sl->sl_items[i];
1160 
1161 	if (i == 0)
1162 	    li->li_prev = NULL;
1163 	else
1164 	    li->li_prev = li - 1;
1165 	if (i == 9)
1166 	    li->li_next = NULL;
1167 	else
1168 	    li->li_next = li + 1;
1169     }
1170 }
1171 
1172 /*
1173  * "list2str()" function
1174  */
1175     void
1176 f_list2str(typval_T *argvars, typval_T *rettv)
1177 {
1178     list_T	*l;
1179     listitem_T	*li;
1180     garray_T	ga;
1181     int		utf8 = FALSE;
1182 
1183     rettv->v_type = VAR_STRING;
1184     rettv->vval.v_string = NULL;
1185     if (argvars[0].v_type != VAR_LIST)
1186     {
1187 	emsg(_(e_invarg));
1188 	return;
1189     }
1190 
1191     l = argvars[0].vval.v_list;
1192     if (l == NULL)
1193 	return;  // empty list results in empty string
1194 
1195     if (argvars[1].v_type != VAR_UNKNOWN)
1196 	utf8 = (int)tv_get_number_chk(&argvars[1], NULL);
1197 
1198     range_list_materialize(l);
1199     ga_init2(&ga, 1, 80);
1200     if (has_mbyte || utf8)
1201     {
1202 	char_u	buf[MB_MAXBYTES + 1];
1203 	int	(*char2bytes)(int, char_u *);
1204 
1205 	if (utf8 || enc_utf8)
1206 	    char2bytes = utf_char2bytes;
1207 	else
1208 	    char2bytes = mb_char2bytes;
1209 
1210 	for (li = l->lv_first; li != NULL; li = li->li_next)
1211 	{
1212 	    buf[(*char2bytes)(tv_get_number(&li->li_tv), buf)] = NUL;
1213 	    ga_concat(&ga, buf);
1214 	}
1215 	ga_append(&ga, NUL);
1216     }
1217     else if (ga_grow(&ga, list_len(l) + 1) == OK)
1218     {
1219 	for (li = l->lv_first; li != NULL; li = li->li_next)
1220 	    ga_append(&ga, tv_get_number(&li->li_tv));
1221 	ga_append(&ga, NUL);
1222     }
1223 
1224     rettv->v_type = VAR_STRING;
1225     rettv->vval.v_string = ga.ga_data;
1226 }
1227 
1228     void
1229 list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
1230 {
1231     list_T	*l;
1232     listitem_T	*item, *item2;
1233     listitem_T	*li;
1234     int		error = FALSE;
1235     int		idx;
1236 
1237     if ((l = argvars[0].vval.v_list) == NULL
1238 			      || var_check_lock(l->lv_lock, arg_errmsg, TRUE))
1239 	return;
1240 
1241     idx = (long)tv_get_number_chk(&argvars[1], &error);
1242     if (error)
1243 	;		// type error: do nothing, errmsg already given
1244     else if ((item = list_find(l, idx)) == NULL)
1245 	semsg(_(e_listidx), idx);
1246     else
1247     {
1248 	if (argvars[2].v_type == VAR_UNKNOWN)
1249 	{
1250 	    // Remove one item, return its value.
1251 	    vimlist_remove(l, item, item);
1252 	    *rettv = item->li_tv;
1253 	    list_free_item(l, item);
1254 	}
1255 	else
1256 	{
1257 	    // Remove range of items, return list with values.
1258 	    int end = (long)tv_get_number_chk(&argvars[2], &error);
1259 
1260 	    if (error)
1261 		;		// type error: do nothing
1262 	    else if ((item2 = list_find(l, end)) == NULL)
1263 		semsg(_(e_listidx), end);
1264 	    else
1265 	    {
1266 		int	    cnt = 0;
1267 
1268 		for (li = item; li != NULL; li = li->li_next)
1269 		{
1270 		    ++cnt;
1271 		    if (li == item2)
1272 			break;
1273 		}
1274 		if (li == NULL)  // didn't find "item2" after "item"
1275 		    emsg(_(e_invrange));
1276 		else
1277 		{
1278 		    vimlist_remove(l, item, item2);
1279 		    if (rettv_list_alloc(rettv) == OK)
1280 		    {
1281 			l = rettv->vval.v_list;
1282 			l->lv_first = item;
1283 			l->lv_u.mat.lv_last = item2;
1284 			item->li_prev = NULL;
1285 			item2->li_next = NULL;
1286 			l->lv_len = cnt;
1287 		    }
1288 		}
1289 	    }
1290 	}
1291     }
1292 }
1293 
1294 static int item_compare(const void *s1, const void *s2);
1295 static int item_compare2(const void *s1, const void *s2);
1296 
1297 // struct used in the array that's given to qsort()
1298 typedef struct
1299 {
1300     listitem_T	*item;
1301     int		idx;
1302 } sortItem_T;
1303 
1304 // struct storing information about current sort
1305 typedef struct
1306 {
1307     int		item_compare_ic;
1308     int		item_compare_numeric;
1309     int		item_compare_numbers;
1310 #ifdef FEAT_FLOAT
1311     int		item_compare_float;
1312 #endif
1313     char_u	*item_compare_func;
1314     partial_T	*item_compare_partial;
1315     dict_T	*item_compare_selfdict;
1316     int		item_compare_func_err;
1317     int		item_compare_keep_zero;
1318 } sortinfo_T;
1319 static sortinfo_T	*sortinfo = NULL;
1320 #define ITEM_COMPARE_FAIL 999
1321 
1322 /*
1323  * Compare functions for f_sort() and f_uniq() below.
1324  */
1325     static int
1326 item_compare(const void *s1, const void *s2)
1327 {
1328     sortItem_T  *si1, *si2;
1329     typval_T	*tv1, *tv2;
1330     char_u	*p1, *p2;
1331     char_u	*tofree1 = NULL, *tofree2 = NULL;
1332     int		res;
1333     char_u	numbuf1[NUMBUFLEN];
1334     char_u	numbuf2[NUMBUFLEN];
1335 
1336     si1 = (sortItem_T *)s1;
1337     si2 = (sortItem_T *)s2;
1338     tv1 = &si1->item->li_tv;
1339     tv2 = &si2->item->li_tv;
1340 
1341     if (sortinfo->item_compare_numbers)
1342     {
1343 	varnumber_T	v1 = tv_get_number(tv1);
1344 	varnumber_T	v2 = tv_get_number(tv2);
1345 
1346 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
1347     }
1348 
1349 #ifdef FEAT_FLOAT
1350     if (sortinfo->item_compare_float)
1351     {
1352 	float_T	v1 = tv_get_float(tv1);
1353 	float_T	v2 = tv_get_float(tv2);
1354 
1355 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
1356     }
1357 #endif
1358 
1359     // tv2string() puts quotes around a string and allocates memory.  Don't do
1360     // that for string variables. Use a single quote when comparing with a
1361     // non-string to do what the docs promise.
1362     if (tv1->v_type == VAR_STRING)
1363     {
1364 	if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric)
1365 	    p1 = (char_u *)"'";
1366 	else
1367 	    p1 = tv1->vval.v_string;
1368     }
1369     else
1370 	p1 = tv2string(tv1, &tofree1, numbuf1, 0);
1371     if (tv2->v_type == VAR_STRING)
1372     {
1373 	if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric)
1374 	    p2 = (char_u *)"'";
1375 	else
1376 	    p2 = tv2->vval.v_string;
1377     }
1378     else
1379 	p2 = tv2string(tv2, &tofree2, numbuf2, 0);
1380     if (p1 == NULL)
1381 	p1 = (char_u *)"";
1382     if (p2 == NULL)
1383 	p2 = (char_u *)"";
1384     if (!sortinfo->item_compare_numeric)
1385     {
1386 	if (sortinfo->item_compare_ic)
1387 	    res = STRICMP(p1, p2);
1388 	else
1389 	    res = STRCMP(p1, p2);
1390     }
1391     else
1392     {
1393 	double n1, n2;
1394 	n1 = strtod((char *)p1, (char **)&p1);
1395 	n2 = strtod((char *)p2, (char **)&p2);
1396 	res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
1397     }
1398 
1399     // When the result would be zero, compare the item indexes.  Makes the
1400     // sort stable.
1401     if (res == 0 && !sortinfo->item_compare_keep_zero)
1402 	res = si1->idx > si2->idx ? 1 : -1;
1403 
1404     vim_free(tofree1);
1405     vim_free(tofree2);
1406     return res;
1407 }
1408 
1409     static int
1410 item_compare2(const void *s1, const void *s2)
1411 {
1412     sortItem_T  *si1, *si2;
1413     int		res;
1414     typval_T	rettv;
1415     typval_T	argv[3];
1416     char_u	*func_name;
1417     partial_T	*partial = sortinfo->item_compare_partial;
1418     funcexe_T	funcexe;
1419 
1420     // shortcut after failure in previous call; compare all items equal
1421     if (sortinfo->item_compare_func_err)
1422 	return 0;
1423 
1424     si1 = (sortItem_T *)s1;
1425     si2 = (sortItem_T *)s2;
1426 
1427     if (partial == NULL)
1428 	func_name = sortinfo->item_compare_func;
1429     else
1430 	func_name = partial_name(partial);
1431 
1432     // Copy the values.  This is needed to be able to set v_lock to VAR_FIXED
1433     // in the copy without changing the original list items.
1434     copy_tv(&si1->item->li_tv, &argv[0]);
1435     copy_tv(&si2->item->li_tv, &argv[1]);
1436 
1437     rettv.v_type = VAR_UNKNOWN;		// clear_tv() uses this
1438     vim_memset(&funcexe, 0, sizeof(funcexe));
1439     funcexe.evaluate = TRUE;
1440     funcexe.partial = partial;
1441     funcexe.selfdict = sortinfo->item_compare_selfdict;
1442     res = call_func(func_name, -1, &rettv, 2, argv, &funcexe);
1443     clear_tv(&argv[0]);
1444     clear_tv(&argv[1]);
1445 
1446     if (res == FAIL)
1447 	res = ITEM_COMPARE_FAIL;
1448     else
1449 	res = (int)tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err);
1450     if (sortinfo->item_compare_func_err)
1451 	res = ITEM_COMPARE_FAIL;  // return value has wrong type
1452     clear_tv(&rettv);
1453 
1454     // When the result would be zero, compare the pointers themselves.  Makes
1455     // the sort stable.
1456     if (res == 0 && !sortinfo->item_compare_keep_zero)
1457 	res = si1->idx > si2->idx ? 1 : -1;
1458 
1459     return res;
1460 }
1461 
1462 /*
1463  * "sort()" or "uniq()" function
1464  */
1465     static void
1466 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
1467 {
1468     list_T	*l;
1469     listitem_T	*li;
1470     sortItem_T	*ptrs;
1471     sortinfo_T	*old_sortinfo;
1472     sortinfo_T	info;
1473     long	len;
1474     long	i;
1475 
1476     // Pointer to current info struct used in compare function. Save and
1477     // restore the current one for nested calls.
1478     old_sortinfo = sortinfo;
1479     sortinfo = &info;
1480 
1481     if (argvars[0].v_type != VAR_LIST)
1482 	semsg(_(e_listarg), sort ? "sort()" : "uniq()");
1483     else
1484     {
1485 	l = argvars[0].vval.v_list;
1486 	if (l == NULL || var_check_lock(l->lv_lock,
1487 	     (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")),
1488 									TRUE))
1489 	    goto theend;
1490 	rettv_list_set(rettv, l);
1491 	range_list_materialize(l);
1492 
1493 	len = list_len(l);
1494 	if (len <= 1)
1495 	    goto theend;	// short list sorts pretty quickly
1496 
1497 	info.item_compare_ic = FALSE;
1498 	info.item_compare_numeric = FALSE;
1499 	info.item_compare_numbers = FALSE;
1500 #ifdef FEAT_FLOAT
1501 	info.item_compare_float = FALSE;
1502 #endif
1503 	info.item_compare_func = NULL;
1504 	info.item_compare_partial = NULL;
1505 	info.item_compare_selfdict = NULL;
1506 	if (argvars[1].v_type != VAR_UNKNOWN)
1507 	{
1508 	    // optional second argument: {func}
1509 	    if (argvars[1].v_type == VAR_FUNC)
1510 		info.item_compare_func = argvars[1].vval.v_string;
1511 	    else if (argvars[1].v_type == VAR_PARTIAL)
1512 		info.item_compare_partial = argvars[1].vval.v_partial;
1513 	    else
1514 	    {
1515 		int	    error = FALSE;
1516 
1517 		i = (long)tv_get_number_chk(&argvars[1], &error);
1518 		if (error)
1519 		    goto theend;	// type error; errmsg already given
1520 		if (i == 1)
1521 		    info.item_compare_ic = TRUE;
1522 		else if (argvars[1].v_type != VAR_NUMBER)
1523 		    info.item_compare_func = tv_get_string(&argvars[1]);
1524 		else if (i != 0)
1525 		{
1526 		    emsg(_(e_invarg));
1527 		    goto theend;
1528 		}
1529 		if (info.item_compare_func != NULL)
1530 		{
1531 		    if (*info.item_compare_func == NUL)
1532 		    {
1533 			// empty string means default sort
1534 			info.item_compare_func = NULL;
1535 		    }
1536 		    else if (STRCMP(info.item_compare_func, "n") == 0)
1537 		    {
1538 			info.item_compare_func = NULL;
1539 			info.item_compare_numeric = TRUE;
1540 		    }
1541 		    else if (STRCMP(info.item_compare_func, "N") == 0)
1542 		    {
1543 			info.item_compare_func = NULL;
1544 			info.item_compare_numbers = TRUE;
1545 		    }
1546 #ifdef FEAT_FLOAT
1547 		    else if (STRCMP(info.item_compare_func, "f") == 0)
1548 		    {
1549 			info.item_compare_func = NULL;
1550 			info.item_compare_float = TRUE;
1551 		    }
1552 #endif
1553 		    else if (STRCMP(info.item_compare_func, "i") == 0)
1554 		    {
1555 			info.item_compare_func = NULL;
1556 			info.item_compare_ic = TRUE;
1557 		    }
1558 		}
1559 	    }
1560 
1561 	    if (argvars[2].v_type != VAR_UNKNOWN)
1562 	    {
1563 		// optional third argument: {dict}
1564 		if (argvars[2].v_type != VAR_DICT)
1565 		{
1566 		    emsg(_(e_dictreq));
1567 		    goto theend;
1568 		}
1569 		info.item_compare_selfdict = argvars[2].vval.v_dict;
1570 	    }
1571 	}
1572 
1573 	// Make an array with each entry pointing to an item in the List.
1574 	ptrs = ALLOC_MULT(sortItem_T, len);
1575 	if (ptrs == NULL)
1576 	    goto theend;
1577 
1578 	i = 0;
1579 	if (sort)
1580 	{
1581 	    // sort(): ptrs will be the list to sort
1582 	    for (li = l->lv_first; li != NULL; li = li->li_next)
1583 	    {
1584 		ptrs[i].item = li;
1585 		ptrs[i].idx = i;
1586 		++i;
1587 	    }
1588 
1589 	    info.item_compare_func_err = FALSE;
1590 	    info.item_compare_keep_zero = FALSE;
1591 	    // test the compare function
1592 	    if ((info.item_compare_func != NULL
1593 					 || info.item_compare_partial != NULL)
1594 		    && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
1595 							 == ITEM_COMPARE_FAIL)
1596 		emsg(_("E702: Sort compare function failed"));
1597 	    else
1598 	    {
1599 		// Sort the array with item pointers.
1600 		qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T),
1601 		    info.item_compare_func == NULL
1602 					  && info.item_compare_partial == NULL
1603 					       ? item_compare : item_compare2);
1604 
1605 		if (!info.item_compare_func_err)
1606 		{
1607 		    // Clear the List and append the items in sorted order.
1608 		    l->lv_first = l->lv_u.mat.lv_last
1609 					      = l->lv_u.mat.lv_idx_item = NULL;
1610 		    l->lv_len = 0;
1611 		    for (i = 0; i < len; ++i)
1612 			list_append(l, ptrs[i].item);
1613 		}
1614 	    }
1615 	}
1616 	else
1617 	{
1618 	    int	(*item_compare_func_ptr)(const void *, const void *);
1619 
1620 	    // f_uniq(): ptrs will be a stack of items to remove
1621 	    info.item_compare_func_err = FALSE;
1622 	    info.item_compare_keep_zero = TRUE;
1623 	    item_compare_func_ptr = info.item_compare_func != NULL
1624 					  || info.item_compare_partial != NULL
1625 					       ? item_compare2 : item_compare;
1626 
1627 	    for (li = l->lv_first; li != NULL && li->li_next != NULL;
1628 							     li = li->li_next)
1629 	    {
1630 		if (item_compare_func_ptr((void *)&li, (void *)&li->li_next)
1631 									 == 0)
1632 		    ptrs[i++].item = li;
1633 		if (info.item_compare_func_err)
1634 		{
1635 		    emsg(_("E882: Uniq compare function failed"));
1636 		    break;
1637 		}
1638 	    }
1639 
1640 	    if (!info.item_compare_func_err)
1641 	    {
1642 		while (--i >= 0)
1643 		{
1644 		    li = ptrs[i].item->li_next;
1645 		    ptrs[i].item->li_next = li->li_next;
1646 		    if (li->li_next != NULL)
1647 			li->li_next->li_prev = ptrs[i].item;
1648 		    else
1649 			l->lv_u.mat.lv_last = ptrs[i].item;
1650 		    list_fix_watch(l, li);
1651 		    listitem_free(l, li);
1652 		    l->lv_len--;
1653 		}
1654 	    }
1655 	}
1656 
1657 	vim_free(ptrs);
1658     }
1659 theend:
1660     sortinfo = old_sortinfo;
1661 }
1662 
1663 /*
1664  * "sort({list})" function
1665  */
1666     void
1667 f_sort(typval_T *argvars, typval_T *rettv)
1668 {
1669     do_sort_uniq(argvars, rettv, TRUE);
1670 }
1671 
1672 /*
1673  * "uniq({list})" function
1674  */
1675     void
1676 f_uniq(typval_T *argvars, typval_T *rettv)
1677 {
1678     do_sort_uniq(argvars, rettv, FALSE);
1679 }
1680 
1681 /*
1682  * Handle one item for map() and filter().
1683  */
1684     static int
1685 filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
1686 {
1687     typval_T	rettv;
1688     typval_T	argv[3];
1689     int		retval = FAIL;
1690 
1691     copy_tv(tv, get_vim_var_tv(VV_VAL));
1692     argv[0] = *get_vim_var_tv(VV_KEY);
1693     argv[1] = *get_vim_var_tv(VV_VAL);
1694     if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL)
1695 	goto theend;
1696     if (map)
1697     {
1698 	// map(): replace the list item value
1699 	clear_tv(tv);
1700 	rettv.v_lock = 0;
1701 	*tv = rettv;
1702     }
1703     else
1704     {
1705 	int	    error = FALSE;
1706 
1707 	// filter(): when expr is zero remove the item
1708 	*remp = (tv_get_number_chk(&rettv, &error) == 0);
1709 	clear_tv(&rettv);
1710 	// On type error, nothing has been removed; return FAIL to stop the
1711 	// loop.  The error message was given by tv_get_number_chk().
1712 	if (error)
1713 	    goto theend;
1714     }
1715     retval = OK;
1716 theend:
1717     clear_tv(get_vim_var_tv(VV_VAL));
1718     return retval;
1719 }
1720 
1721 /*
1722  * Implementation of map() and filter().
1723  */
1724     static void
1725 filter_map(typval_T *argvars, typval_T *rettv, int map)
1726 {
1727     typval_T	*expr;
1728     listitem_T	*li, *nli;
1729     list_T	*l = NULL;
1730     dictitem_T	*di;
1731     hashtab_T	*ht;
1732     hashitem_T	*hi;
1733     dict_T	*d = NULL;
1734     blob_T	*b = NULL;
1735     int		rem;
1736     int		todo;
1737     char_u	*ermsg = (char_u *)(map ? "map()" : "filter()");
1738     char_u	*arg_errmsg = (char_u *)(map ? N_("map() argument")
1739 				   : N_("filter() argument"));
1740     int		save_did_emsg;
1741     int		idx = 0;
1742 
1743     if (argvars[0].v_type == VAR_BLOB)
1744     {
1745 	if ((b = argvars[0].vval.v_blob) == NULL)
1746 	    return;
1747     }
1748     else if (argvars[0].v_type == VAR_LIST)
1749     {
1750 	if ((l = argvars[0].vval.v_list) == NULL
1751 	      || (!map && var_check_lock(l->lv_lock, arg_errmsg, TRUE)))
1752 	    return;
1753     }
1754     else if (argvars[0].v_type == VAR_DICT)
1755     {
1756 	if ((d = argvars[0].vval.v_dict) == NULL
1757 	      || (!map && var_check_lock(d->dv_lock, arg_errmsg, TRUE)))
1758 	    return;
1759     }
1760     else
1761     {
1762 	semsg(_(e_listdictarg), ermsg);
1763 	return;
1764     }
1765 
1766     expr = &argvars[1];
1767     // On type errors, the preceding call has already displayed an error
1768     // message.  Avoid a misleading error message for an empty string that
1769     // was not passed as argument.
1770     if (expr->v_type != VAR_UNKNOWN)
1771     {
1772 	typval_T	save_val;
1773 	typval_T	save_key;
1774 
1775 	prepare_vimvar(VV_VAL, &save_val);
1776 	prepare_vimvar(VV_KEY, &save_key);
1777 
1778 	// We reset "did_emsg" to be able to detect whether an error
1779 	// occurred during evaluation of the expression.
1780 	save_did_emsg = did_emsg;
1781 	did_emsg = FALSE;
1782 
1783 	if (argvars[0].v_type == VAR_DICT)
1784 	{
1785 	    int	    prev_lock = d->dv_lock;
1786 
1787 	    if (map && d->dv_lock == 0)
1788 		d->dv_lock = VAR_LOCKED;
1789 	    ht = &d->dv_hashtab;
1790 	    hash_lock(ht);
1791 	    todo = (int)ht->ht_used;
1792 	    for (hi = ht->ht_array; todo > 0; ++hi)
1793 	    {
1794 		if (!HASHITEM_EMPTY(hi))
1795 		{
1796 		    int r;
1797 
1798 		    --todo;
1799 		    di = HI2DI(hi);
1800 		    if (map && (var_check_lock(di->di_tv.v_lock,
1801 							   arg_errmsg, TRUE)
1802 				|| var_check_ro(di->di_flags,
1803 							   arg_errmsg, TRUE)))
1804 			break;
1805 		    set_vim_var_string(VV_KEY, di->di_key, -1);
1806 		    r = filter_map_one(&di->di_tv, expr, map, &rem);
1807 		    clear_tv(get_vim_var_tv(VV_KEY));
1808 		    if (r == FAIL || did_emsg)
1809 			break;
1810 		    if (!map && rem)
1811 		    {
1812 			if (var_check_fixed(di->di_flags, arg_errmsg, TRUE)
1813 			    || var_check_ro(di->di_flags, arg_errmsg, TRUE))
1814 			    break;
1815 			dictitem_remove(d, di);
1816 		    }
1817 		}
1818 	    }
1819 	    hash_unlock(ht);
1820 	    d->dv_lock = prev_lock;
1821 	}
1822 	else if (argvars[0].v_type == VAR_BLOB)
1823 	{
1824 	    int		i;
1825 	    typval_T	tv;
1826 	    varnumber_T	val;
1827 
1828 	    // set_vim_var_nr() doesn't set the type
1829 	    set_vim_var_type(VV_KEY, VAR_NUMBER);
1830 
1831 	    for (i = 0; i < b->bv_ga.ga_len; i++)
1832 	    {
1833 		tv.v_type = VAR_NUMBER;
1834 		val = blob_get(b, i);
1835 		tv.vval.v_number = val;
1836 		set_vim_var_nr(VV_KEY, idx);
1837 		if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg)
1838 		    break;
1839 		if (tv.v_type != VAR_NUMBER)
1840 		{
1841 		    emsg(_(e_invalblob));
1842 		    break;
1843 		}
1844 		if (map)
1845 		{
1846 		    if (tv.vval.v_number != val)
1847 			blob_set(b, i, tv.vval.v_number);
1848 		}
1849 		else if (rem)
1850 		{
1851 		    char_u *p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
1852 
1853 		    mch_memmove(p + i, p + i + 1,
1854 					      (size_t)b->bv_ga.ga_len - i - 1);
1855 		    --b->bv_ga.ga_len;
1856 		    --i;
1857 		}
1858 		++idx;
1859 	    }
1860 	}
1861 	else // argvars[0].v_type == VAR_LIST
1862 	{
1863 	    int prev_lock = l->lv_lock;
1864 
1865 	    // set_vim_var_nr() doesn't set the type
1866 	    set_vim_var_type(VV_KEY, VAR_NUMBER);
1867 
1868 	    range_list_materialize(l);
1869 	    if (map && l->lv_lock == 0)
1870 		l->lv_lock = VAR_LOCKED;
1871 	    for (li = l->lv_first; li != NULL; li = nli)
1872 	    {
1873 		if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE))
1874 		    break;
1875 		nli = li->li_next;
1876 		set_vim_var_nr(VV_KEY, idx);
1877 		if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
1878 								  || did_emsg)
1879 		    break;
1880 		if (!map && rem)
1881 		    listitem_remove(l, li);
1882 		++idx;
1883 	    }
1884 	    l->lv_lock = prev_lock;
1885 	}
1886 
1887 	restore_vimvar(VV_KEY, &save_key);
1888 	restore_vimvar(VV_VAL, &save_val);
1889 
1890 	did_emsg |= save_did_emsg;
1891     }
1892 
1893     copy_tv(&argvars[0], rettv);
1894 }
1895 
1896 /*
1897  * "filter()" function
1898  */
1899     void
1900 f_filter(typval_T *argvars, typval_T *rettv)
1901 {
1902     filter_map(argvars, rettv, FALSE);
1903 }
1904 
1905 /*
1906  * "map()" function
1907  */
1908     void
1909 f_map(typval_T *argvars, typval_T *rettv)
1910 {
1911     filter_map(argvars, rettv, TRUE);
1912 }
1913 
1914 /*
1915  * "add(list, item)" function
1916  */
1917     void
1918 f_add(typval_T *argvars, typval_T *rettv)
1919 {
1920     list_T	*l;
1921     blob_T	*b;
1922 
1923     rettv->vval.v_number = 1; // Default: Failed
1924     if (argvars[0].v_type == VAR_LIST)
1925     {
1926 	if ((l = argvars[0].vval.v_list) != NULL
1927 		&& !var_check_lock(l->lv_lock,
1928 					 (char_u *)N_("add() argument"), TRUE)
1929 		&& list_append_tv(l, &argvars[1]) == OK)
1930 	    copy_tv(&argvars[0], rettv);
1931     }
1932     else if (argvars[0].v_type == VAR_BLOB)
1933     {
1934 	if ((b = argvars[0].vval.v_blob) != NULL
1935 		&& !var_check_lock(b->bv_lock,
1936 					 (char_u *)N_("add() argument"), TRUE))
1937 	{
1938 	    int		error = FALSE;
1939 	    varnumber_T n = tv_get_number_chk(&argvars[1], &error);
1940 
1941 	    if (!error)
1942 	    {
1943 		ga_append(&b->bv_ga, (int)n);
1944 		copy_tv(&argvars[0], rettv);
1945 	    }
1946 	}
1947     }
1948     else
1949 	emsg(_(e_listblobreq));
1950 }
1951 
1952 /*
1953  * "count()" function
1954  */
1955     void
1956 f_count(typval_T *argvars, typval_T *rettv)
1957 {
1958     long	n = 0;
1959     int		ic = FALSE;
1960     int		error = FALSE;
1961 
1962     if (argvars[2].v_type != VAR_UNKNOWN)
1963 	ic = (int)tv_get_number_chk(&argvars[2], &error);
1964 
1965     if (argvars[0].v_type == VAR_STRING)
1966     {
1967 	char_u *expr = tv_get_string_chk(&argvars[1]);
1968 	char_u *p = argvars[0].vval.v_string;
1969 	char_u *next;
1970 
1971 	if (!error && expr != NULL && *expr != NUL && p != NULL)
1972 	{
1973 	    if (ic)
1974 	    {
1975 		size_t len = STRLEN(expr);
1976 
1977 		while (*p != NUL)
1978 		{
1979 		    if (MB_STRNICMP(p, expr, len) == 0)
1980 		    {
1981 			++n;
1982 			p += len;
1983 		    }
1984 		    else
1985 			MB_PTR_ADV(p);
1986 		}
1987 	    }
1988 	    else
1989 		while ((next = (char_u *)strstr((char *)p, (char *)expr))
1990 								       != NULL)
1991 		{
1992 		    ++n;
1993 		    p = next + STRLEN(expr);
1994 		}
1995 	}
1996 
1997     }
1998     else if (argvars[0].v_type == VAR_LIST)
1999     {
2000 	listitem_T	*li;
2001 	list_T		*l;
2002 	long		idx;
2003 
2004 	if ((l = argvars[0].vval.v_list) != NULL)
2005 	{
2006 	    range_list_materialize(l);
2007 	    li = l->lv_first;
2008 	    if (argvars[2].v_type != VAR_UNKNOWN)
2009 	    {
2010 		if (argvars[3].v_type != VAR_UNKNOWN)
2011 		{
2012 		    idx = (long)tv_get_number_chk(&argvars[3], &error);
2013 		    if (!error)
2014 		    {
2015 			li = list_find(l, idx);
2016 			if (li == NULL)
2017 			    semsg(_(e_listidx), idx);
2018 		    }
2019 		}
2020 		if (error)
2021 		    li = NULL;
2022 	    }
2023 
2024 	    for ( ; li != NULL; li = li->li_next)
2025 		if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE))
2026 		    ++n;
2027 	}
2028     }
2029     else if (argvars[0].v_type == VAR_DICT)
2030     {
2031 	int		todo;
2032 	dict_T		*d;
2033 	hashitem_T	*hi;
2034 
2035 	if ((d = argvars[0].vval.v_dict) != NULL)
2036 	{
2037 	    if (argvars[2].v_type != VAR_UNKNOWN)
2038 	    {
2039 		if (argvars[3].v_type != VAR_UNKNOWN)
2040 		    emsg(_(e_invarg));
2041 	    }
2042 
2043 	    todo = error ? 0 : (int)d->dv_hashtab.ht_used;
2044 	    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
2045 	    {
2046 		if (!HASHITEM_EMPTY(hi))
2047 		{
2048 		    --todo;
2049 		    if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE))
2050 			++n;
2051 		}
2052 	    }
2053 	}
2054     }
2055     else
2056 	semsg(_(e_listdictarg), "count()");
2057     rettv->vval.v_number = n;
2058 }
2059 
2060 /*
2061  * "extend(list, list [, idx])" function
2062  * "extend(dict, dict [, action])" function
2063  */
2064     void
2065 f_extend(typval_T *argvars, typval_T *rettv)
2066 {
2067     char_u      *arg_errmsg = (char_u *)N_("extend() argument");
2068 
2069     if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
2070     {
2071 	list_T		*l1, *l2;
2072 	listitem_T	*item;
2073 	long		before;
2074 	int		error = FALSE;
2075 
2076 	l1 = argvars[0].vval.v_list;
2077 	l2 = argvars[1].vval.v_list;
2078 	if (l1 != NULL && !var_check_lock(l1->lv_lock, arg_errmsg, TRUE)
2079 		&& l2 != NULL)
2080 	{
2081 	    if (argvars[2].v_type != VAR_UNKNOWN)
2082 	    {
2083 		before = (long)tv_get_number_chk(&argvars[2], &error);
2084 		if (error)
2085 		    return;		// type error; errmsg already given
2086 
2087 		if (before == l1->lv_len)
2088 		    item = NULL;
2089 		else
2090 		{
2091 		    item = list_find(l1, before);
2092 		    if (item == NULL)
2093 		    {
2094 			semsg(_(e_listidx), before);
2095 			return;
2096 		    }
2097 		}
2098 	    }
2099 	    else
2100 		item = NULL;
2101 	    list_extend(l1, l2, item);
2102 
2103 	    copy_tv(&argvars[0], rettv);
2104 	}
2105     }
2106     else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
2107     {
2108 	dict_T	*d1, *d2;
2109 	char_u	*action;
2110 	int	i;
2111 
2112 	d1 = argvars[0].vval.v_dict;
2113 	d2 = argvars[1].vval.v_dict;
2114 	if (d1 != NULL && !var_check_lock(d1->dv_lock, arg_errmsg, TRUE)
2115 		&& d2 != NULL)
2116 	{
2117 	    // Check the third argument.
2118 	    if (argvars[2].v_type != VAR_UNKNOWN)
2119 	    {
2120 		static char *(av[]) = {"keep", "force", "error"};
2121 
2122 		action = tv_get_string_chk(&argvars[2]);
2123 		if (action == NULL)
2124 		    return;		// type error; errmsg already given
2125 		for (i = 0; i < 3; ++i)
2126 		    if (STRCMP(action, av[i]) == 0)
2127 			break;
2128 		if (i == 3)
2129 		{
2130 		    semsg(_(e_invarg2), action);
2131 		    return;
2132 		}
2133 	    }
2134 	    else
2135 		action = (char_u *)"force";
2136 
2137 	    dict_extend(d1, d2, action);
2138 
2139 	    copy_tv(&argvars[0], rettv);
2140 	}
2141     }
2142     else
2143 	semsg(_(e_listdictarg), "extend()");
2144 }
2145 
2146 /*
2147  * "insert()" function
2148  */
2149     void
2150 f_insert(typval_T *argvars, typval_T *rettv)
2151 {
2152     long	before = 0;
2153     listitem_T	*item;
2154     list_T	*l;
2155     int		error = FALSE;
2156 
2157     if (argvars[0].v_type == VAR_BLOB)
2158     {
2159 	int	    val, len;
2160 	char_u	    *p;
2161 
2162 	len = blob_len(argvars[0].vval.v_blob);
2163 	if (argvars[2].v_type != VAR_UNKNOWN)
2164 	{
2165 	    before = (long)tv_get_number_chk(&argvars[2], &error);
2166 	    if (error)
2167 		return;		// type error; errmsg already given
2168 	    if (before < 0 || before > len)
2169 	    {
2170 		semsg(_(e_invarg2), tv_get_string(&argvars[2]));
2171 		return;
2172 	    }
2173 	}
2174 	val = tv_get_number_chk(&argvars[1], &error);
2175 	if (error)
2176 	    return;
2177 	if (val < 0 || val > 255)
2178 	{
2179 	    semsg(_(e_invarg2), tv_get_string(&argvars[1]));
2180 	    return;
2181 	}
2182 
2183 	if (ga_grow(&argvars[0].vval.v_blob->bv_ga, 1) == FAIL)
2184 	    return;
2185 	p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
2186 	mch_memmove(p + before + 1, p + before, (size_t)len - before);
2187 	*(p + before) = val;
2188 	++argvars[0].vval.v_blob->bv_ga.ga_len;
2189 
2190 	copy_tv(&argvars[0], rettv);
2191     }
2192     else if (argvars[0].v_type != VAR_LIST)
2193 	semsg(_(e_listblobarg), "insert()");
2194     else if ((l = argvars[0].vval.v_list) != NULL
2195 	    && !var_check_lock(l->lv_lock,
2196 				     (char_u *)N_("insert() argument"), TRUE))
2197     {
2198 	if (argvars[2].v_type != VAR_UNKNOWN)
2199 	    before = (long)tv_get_number_chk(&argvars[2], &error);
2200 	if (error)
2201 	    return;		// type error; errmsg already given
2202 
2203 	if (before == l->lv_len)
2204 	    item = NULL;
2205 	else
2206 	{
2207 	    item = list_find(l, before);
2208 	    if (item == NULL)
2209 	    {
2210 		semsg(_(e_listidx), before);
2211 		l = NULL;
2212 	    }
2213 	}
2214 	if (l != NULL)
2215 	{
2216 	    list_insert_tv(l, &argvars[1], item);
2217 	    copy_tv(&argvars[0], rettv);
2218 	}
2219     }
2220 }
2221 
2222 /*
2223  * "remove()" function
2224  */
2225     void
2226 f_remove(typval_T *argvars, typval_T *rettv)
2227 {
2228     char_u	*arg_errmsg = (char_u *)N_("remove() argument");
2229 
2230     if (argvars[0].v_type == VAR_DICT)
2231 	dict_remove(argvars, rettv, arg_errmsg);
2232     else if (argvars[0].v_type == VAR_BLOB)
2233 	blob_remove(argvars, rettv);
2234     else if (argvars[0].v_type == VAR_LIST)
2235 	list_remove(argvars, rettv, arg_errmsg);
2236     else
2237 	semsg(_(e_listdictblobarg), "remove()");
2238 }
2239 
2240 /*
2241  * "reverse({list})" function
2242  */
2243     void
2244 f_reverse(typval_T *argvars, typval_T *rettv)
2245 {
2246     list_T	*l;
2247     listitem_T	*li, *ni;
2248 
2249     if (argvars[0].v_type == VAR_BLOB)
2250     {
2251 	blob_T	*b = argvars[0].vval.v_blob;
2252 	int	i, len = blob_len(b);
2253 
2254 	for (i = 0; i < len / 2; i++)
2255 	{
2256 	    int tmp = blob_get(b, i);
2257 
2258 	    blob_set(b, i, blob_get(b, len - i - 1));
2259 	    blob_set(b, len - i - 1, tmp);
2260 	}
2261 	rettv_blob_set(rettv, b);
2262 	return;
2263     }
2264 
2265     if (argvars[0].v_type != VAR_LIST)
2266 	semsg(_(e_listblobarg), "reverse()");
2267     else if ((l = argvars[0].vval.v_list) != NULL
2268 	    && !var_check_lock(l->lv_lock,
2269 				    (char_u *)N_("reverse() argument"), TRUE))
2270     {
2271 	if (l->lv_first == &range_list_item)
2272 	{
2273 	    varnumber_T new_start = l->lv_u.nonmat.lv_start
2274 				  + (l->lv_len - 1) * l->lv_u.nonmat.lv_stride;
2275 	    l->lv_u.nonmat.lv_end = new_start
2276 			   - (l->lv_u.nonmat.lv_end - l->lv_u.nonmat.lv_start);
2277 	    l->lv_u.nonmat.lv_start = new_start;
2278 	    l->lv_u.nonmat.lv_stride = -l->lv_u.nonmat.lv_stride;
2279 	    rettv_list_set(rettv, l);
2280 	    return;
2281 	}
2282 	li = l->lv_u.mat.lv_last;
2283 	l->lv_first = l->lv_u.mat.lv_last = NULL;
2284 	l->lv_len = 0;
2285 	while (li != NULL)
2286 	{
2287 	    ni = li->li_prev;
2288 	    list_append(l, li);
2289 	    li = ni;
2290 	}
2291 	rettv_list_set(rettv, l);
2292 	l->lv_u.mat.lv_idx = l->lv_len - l->lv_u.mat.lv_idx - 1;
2293     }
2294 }
2295 
2296 #endif // defined(FEAT_EVAL)
2297