xref: /vim-8.2.3635/src/list.c (revision fcfe1a9b)
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
12  */
13 
14 #include "vim.h"
15 
16 #if defined(FEAT_EVAL) || defined(PROTO)
17 
18 /* List heads for garbage collection. */
19 static list_T		*first_list = NULL;	/* list of all lists */
20 
21 /*
22  * Add a watcher to a list.
23  */
24     void
25 list_add_watch(list_T *l, listwatch_T *lw)
26 {
27     lw->lw_next = l->lv_watch;
28     l->lv_watch = lw;
29 }
30 
31 /*
32  * Remove a watcher from a list.
33  * No warning when it isn't found...
34  */
35     void
36 list_rem_watch(list_T *l, listwatch_T *lwrem)
37 {
38     listwatch_T	*lw, **lwp;
39 
40     lwp = &l->lv_watch;
41     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
42     {
43 	if (lw == lwrem)
44 	{
45 	    *lwp = lw->lw_next;
46 	    break;
47 	}
48 	lwp = &lw->lw_next;
49     }
50 }
51 
52 /*
53  * Just before removing an item from a list: advance watchers to the next
54  * item.
55  */
56     void
57 list_fix_watch(list_T *l, listitem_T *item)
58 {
59     listwatch_T	*lw;
60 
61     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
62 	if (lw->lw_item == item)
63 	    lw->lw_item = item->li_next;
64 }
65 
66 /*
67  * Allocate an empty header for a list.
68  * Caller should take care of the reference count.
69  */
70     list_T *
71 list_alloc(void)
72 {
73     list_T  *l;
74 
75     l = ALLOC_CLEAR_ONE(list_T);
76     if (l != NULL)
77     {
78 	/* Prepend the list to the list of lists for garbage collection. */
79 	if (first_list != NULL)
80 	    first_list->lv_used_prev = l;
81 	l->lv_used_prev = NULL;
82 	l->lv_used_next = first_list;
83 	first_list = l;
84     }
85     return l;
86 }
87 
88 /*
89  * list_alloc() with an ID for alloc_fail().
90  */
91     list_T *
92 list_alloc_id(alloc_id_T id UNUSED)
93 {
94 #ifdef FEAT_EVAL
95     if (alloc_fail_id == id && alloc_does_fail(sizeof(list_T)))
96 	return NULL;
97 #endif
98     return (list_alloc());
99 }
100 
101 /*
102  * Allocate an empty list for a return value, with reference count set.
103  * Returns OK or FAIL.
104  */
105     int
106 rettv_list_alloc(typval_T *rettv)
107 {
108     list_T	*l = list_alloc();
109 
110     if (l == NULL)
111 	return FAIL;
112 
113     rettv->v_lock = 0;
114     rettv_list_set(rettv, l);
115     return OK;
116 }
117 
118 /*
119  * Same as rettv_list_alloc() but uses an allocation id for testing.
120  */
121     int
122 rettv_list_alloc_id(typval_T *rettv, alloc_id_T id UNUSED)
123 {
124 #ifdef FEAT_EVAL
125     if (alloc_fail_id == id && alloc_does_fail(sizeof(list_T)))
126 	return FAIL;
127 #endif
128     return rettv_list_alloc(rettv);
129 }
130 
131 
132 /*
133  * Set a list as the return value.  Increments the reference count.
134  */
135     void
136 rettv_list_set(typval_T *rettv, list_T *l)
137 {
138     rettv->v_type = VAR_LIST;
139     rettv->vval.v_list = l;
140     if (l != NULL)
141 	++l->lv_refcount;
142 }
143 
144 /*
145  * Unreference a list: decrement the reference count and free it when it
146  * becomes zero.
147  */
148     void
149 list_unref(list_T *l)
150 {
151     if (l != NULL && --l->lv_refcount <= 0)
152 	list_free(l);
153 }
154 
155 /*
156  * Free a list, including all non-container items it points to.
157  * Ignores the reference count.
158  */
159     static void
160 list_free_contents(list_T *l)
161 {
162     listitem_T *item;
163 
164     for (item = l->lv_first; item != NULL; item = l->lv_first)
165     {
166 	/* Remove the item before deleting it. */
167 	l->lv_first = item->li_next;
168 	clear_tv(&item->li_tv);
169 	vim_free(item);
170     }
171 }
172 
173 /*
174  * Go through the list of lists and free items without the copyID.
175  * But don't free a list that has a watcher (used in a for loop), these
176  * are not referenced anywhere.
177  */
178     int
179 list_free_nonref(int copyID)
180 {
181     list_T	*ll;
182     int		did_free = FALSE;
183 
184     for (ll = first_list; ll != NULL; ll = ll->lv_used_next)
185 	if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
186 						      && ll->lv_watch == NULL)
187 	{
188 	    /* Free the List and ordinary items it contains, but don't recurse
189 	     * into Lists and Dictionaries, they will be in the list of dicts
190 	     * or list of lists. */
191 	    list_free_contents(ll);
192 	    did_free = TRUE;
193 	}
194     return did_free;
195 }
196 
197     static void
198 list_free_list(list_T  *l)
199 {
200     /* Remove the list from the list of lists for garbage collection. */
201     if (l->lv_used_prev == NULL)
202 	first_list = l->lv_used_next;
203     else
204 	l->lv_used_prev->lv_used_next = l->lv_used_next;
205     if (l->lv_used_next != NULL)
206 	l->lv_used_next->lv_used_prev = l->lv_used_prev;
207 
208     vim_free(l);
209 }
210 
211     void
212 list_free_items(int copyID)
213 {
214     list_T	*ll, *ll_next;
215 
216     for (ll = first_list; ll != NULL; ll = ll_next)
217     {
218 	ll_next = ll->lv_used_next;
219 	if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
220 						      && ll->lv_watch == NULL)
221 	{
222 	    /* Free the List and ordinary items it contains, but don't recurse
223 	     * into Lists and Dictionaries, they will be in the list of dicts
224 	     * or list of lists. */
225 	    list_free_list(ll);
226 	}
227     }
228 }
229 
230     void
231 list_free(list_T *l)
232 {
233     if (!in_free_unref_items)
234     {
235 	list_free_contents(l);
236 	list_free_list(l);
237     }
238 }
239 
240 /*
241  * Allocate a list item.
242  * It is not initialized, don't forget to set v_lock.
243  */
244     listitem_T *
245 listitem_alloc(void)
246 {
247     return ALLOC_ONE(listitem_T);
248 }
249 
250 /*
251  * Free a list item.  Also clears the value.  Does not notify watchers.
252  */
253     void
254 listitem_free(listitem_T *item)
255 {
256     clear_tv(&item->li_tv);
257     vim_free(item);
258 }
259 
260 /*
261  * Remove a list item from a List and free it.  Also clears the value.
262  */
263     void
264 listitem_remove(list_T *l, listitem_T *item)
265 {
266     vimlist_remove(l, item, item);
267     listitem_free(item);
268 }
269 
270 /*
271  * Get the number of items in a list.
272  */
273     long
274 list_len(list_T *l)
275 {
276     if (l == NULL)
277 	return 0L;
278     return l->lv_len;
279 }
280 
281 /*
282  * Return TRUE when two lists have exactly the same values.
283  */
284     int
285 list_equal(
286     list_T	*l1,
287     list_T	*l2,
288     int		ic,	/* ignore case for strings */
289     int		recursive)  /* TRUE when used recursively */
290 {
291     listitem_T	*item1, *item2;
292 
293     if (l1 == NULL || l2 == NULL)
294 	return FALSE;
295     if (l1 == l2)
296 	return TRUE;
297     if (list_len(l1) != list_len(l2))
298 	return FALSE;
299 
300     for (item1 = l1->lv_first, item2 = l2->lv_first;
301 	    item1 != NULL && item2 != NULL;
302 			       item1 = item1->li_next, item2 = item2->li_next)
303 	if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
304 	    return FALSE;
305     return item1 == NULL && item2 == NULL;
306 }
307 
308 /*
309  * Locate item with index "n" in list "l" and return it.
310  * A negative index is counted from the end; -1 is the last item.
311  * Returns NULL when "n" is out of range.
312  */
313     listitem_T *
314 list_find(list_T *l, long n)
315 {
316     listitem_T	*item;
317     long	idx;
318 
319     if (l == NULL)
320 	return NULL;
321 
322     /* Negative index is relative to the end. */
323     if (n < 0)
324 	n = l->lv_len + n;
325 
326     /* Check for index out of range. */
327     if (n < 0 || n >= l->lv_len)
328 	return NULL;
329 
330     /* When there is a cached index may start search from there. */
331     if (l->lv_idx_item != NULL)
332     {
333 	if (n < l->lv_idx / 2)
334 	{
335 	    /* closest to the start of the list */
336 	    item = l->lv_first;
337 	    idx = 0;
338 	}
339 	else if (n > (l->lv_idx + l->lv_len) / 2)
340 	{
341 	    /* closest to the end of the list */
342 	    item = l->lv_last;
343 	    idx = l->lv_len - 1;
344 	}
345 	else
346 	{
347 	    /* closest to the cached index */
348 	    item = l->lv_idx_item;
349 	    idx = l->lv_idx;
350 	}
351     }
352     else
353     {
354 	if (n < l->lv_len / 2)
355 	{
356 	    /* closest to the start of the list */
357 	    item = l->lv_first;
358 	    idx = 0;
359 	}
360 	else
361 	{
362 	    /* closest to the end of the list */
363 	    item = l->lv_last;
364 	    idx = l->lv_len - 1;
365 	}
366     }
367 
368     while (n > idx)
369     {
370 	/* search forward */
371 	item = item->li_next;
372 	++idx;
373     }
374     while (n < idx)
375     {
376 	/* search backward */
377 	item = item->li_prev;
378 	--idx;
379     }
380 
381     /* cache the used index */
382     l->lv_idx = idx;
383     l->lv_idx_item = item;
384 
385     return item;
386 }
387 
388 /*
389  * Get list item "l[idx]" as a number.
390  */
391     long
392 list_find_nr(
393     list_T	*l,
394     long	idx,
395     int		*errorp)	/* set to TRUE when something wrong */
396 {
397     listitem_T	*li;
398 
399     li = list_find(l, idx);
400     if (li == NULL)
401     {
402 	if (errorp != NULL)
403 	    *errorp = TRUE;
404 	return -1L;
405     }
406     return (long)tv_get_number_chk(&li->li_tv, errorp);
407 }
408 
409 /*
410  * Get list item "l[idx - 1]" as a string.  Returns NULL for failure.
411  */
412     char_u *
413 list_find_str(list_T *l, long idx)
414 {
415     listitem_T	*li;
416 
417     li = list_find(l, idx - 1);
418     if (li == NULL)
419     {
420 	semsg(_(e_listidx), idx);
421 	return NULL;
422     }
423     return tv_get_string(&li->li_tv);
424 }
425 
426 /*
427  * Locate "item" list "l" and return its index.
428  * Returns -1 when "item" is not in the list.
429  */
430     long
431 list_idx_of_item(list_T *l, listitem_T *item)
432 {
433     long	idx = 0;
434     listitem_T	*li;
435 
436     if (l == NULL)
437 	return -1;
438     idx = 0;
439     for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
440 	++idx;
441     if (li == NULL)
442 	return -1;
443     return idx;
444 }
445 
446 /*
447  * Append item "item" to the end of list "l".
448  */
449     void
450 list_append(list_T *l, listitem_T *item)
451 {
452     if (l->lv_last == NULL)
453     {
454 	/* empty list */
455 	l->lv_first = item;
456 	l->lv_last = item;
457 	item->li_prev = NULL;
458     }
459     else
460     {
461 	l->lv_last->li_next = item;
462 	item->li_prev = l->lv_last;
463 	l->lv_last = item;
464     }
465     ++l->lv_len;
466     item->li_next = NULL;
467 }
468 
469 /*
470  * Append typval_T "tv" to the end of list "l".
471  * Return FAIL when out of memory.
472  */
473     int
474 list_append_tv(list_T *l, typval_T *tv)
475 {
476     listitem_T	*li = listitem_alloc();
477 
478     if (li == NULL)
479 	return FAIL;
480     copy_tv(tv, &li->li_tv);
481     list_append(l, li);
482     return OK;
483 }
484 
485 /*
486  * Add a dictionary to a list.  Used by getqflist().
487  * Return FAIL when out of memory.
488  */
489     int
490 list_append_dict(list_T *list, dict_T *dict)
491 {
492     listitem_T	*li = listitem_alloc();
493 
494     if (li == NULL)
495 	return FAIL;
496     li->li_tv.v_type = VAR_DICT;
497     li->li_tv.v_lock = 0;
498     li->li_tv.vval.v_dict = dict;
499     list_append(list, li);
500     ++dict->dv_refcount;
501     return OK;
502 }
503 
504 /*
505  * Append list2 to list1.
506  * Return FAIL when out of memory.
507  */
508     int
509 list_append_list(list_T *list1, list_T *list2)
510 {
511     listitem_T	*li = listitem_alloc();
512 
513     if (li == NULL)
514 	return FAIL;
515     li->li_tv.v_type = VAR_LIST;
516     li->li_tv.v_lock = 0;
517     li->li_tv.vval.v_list = list2;
518     list_append(list1, li);
519     ++list2->lv_refcount;
520     return OK;
521 }
522 
523 /*
524  * Make a copy of "str" and append it as an item to list "l".
525  * When "len" >= 0 use "str[len]".
526  * Returns FAIL when out of memory.
527  */
528     int
529 list_append_string(list_T *l, char_u *str, int len)
530 {
531     listitem_T *li = listitem_alloc();
532 
533     if (li == NULL)
534 	return FAIL;
535     list_append(l, li);
536     li->li_tv.v_type = VAR_STRING;
537     li->li_tv.v_lock = 0;
538     if (str == NULL)
539 	li->li_tv.vval.v_string = NULL;
540     else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len)
541 						 : vim_strsave(str))) == NULL)
542 	return FAIL;
543     return OK;
544 }
545 
546 /*
547  * Append "n" to list "l".
548  * Returns FAIL when out of memory.
549  */
550     int
551 list_append_number(list_T *l, varnumber_T n)
552 {
553     listitem_T	*li;
554 
555     li = listitem_alloc();
556     if (li == NULL)
557 	return FAIL;
558     li->li_tv.v_type = VAR_NUMBER;
559     li->li_tv.v_lock = 0;
560     li->li_tv.vval.v_number = n;
561     list_append(l, li);
562     return OK;
563 }
564 
565 /*
566  * Insert typval_T "tv" in list "l" before "item".
567  * If "item" is NULL append at the end.
568  * Return FAIL when out of memory.
569  */
570     int
571 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
572 {
573     listitem_T	*ni = listitem_alloc();
574 
575     if (ni == NULL)
576 	return FAIL;
577     copy_tv(tv, &ni->li_tv);
578     list_insert(l, ni, item);
579     return OK;
580 }
581 
582     void
583 list_insert(list_T *l, listitem_T *ni, listitem_T *item)
584 {
585     if (item == NULL)
586 	/* Append new item at end of list. */
587 	list_append(l, ni);
588     else
589     {
590 	/* Insert new item before existing item. */
591 	ni->li_prev = item->li_prev;
592 	ni->li_next = item;
593 	if (item->li_prev == NULL)
594 	{
595 	    l->lv_first = ni;
596 	    ++l->lv_idx;
597 	}
598 	else
599 	{
600 	    item->li_prev->li_next = ni;
601 	    l->lv_idx_item = NULL;
602 	}
603 	item->li_prev = ni;
604 	++l->lv_len;
605     }
606 }
607 
608 /*
609  * Extend "l1" with "l2".
610  * If "bef" is NULL append at the end, otherwise insert before this item.
611  * Returns FAIL when out of memory.
612  */
613     int
614 list_extend(list_T *l1, list_T *l2, listitem_T *bef)
615 {
616     listitem_T	*item;
617     int		todo = l2->lv_len;
618 
619     /* We also quit the loop when we have inserted the original item count of
620      * the list, avoid a hang when we extend a list with itself. */
621     for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next)
622 	if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
623 	    return FAIL;
624     return OK;
625 }
626 
627 /*
628  * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
629  * Return FAIL when out of memory.
630  */
631     int
632 list_concat(list_T *l1, list_T *l2, typval_T *tv)
633 {
634     list_T	*l;
635 
636     if (l1 == NULL || l2 == NULL)
637 	return FAIL;
638 
639     /* make a copy of the first list. */
640     l = list_copy(l1, FALSE, 0);
641     if (l == NULL)
642 	return FAIL;
643     tv->v_type = VAR_LIST;
644     tv->vval.v_list = l;
645 
646     /* append all items from the second list */
647     return list_extend(l, l2, NULL);
648 }
649 
650 /*
651  * Make a copy of list "orig".  Shallow if "deep" is FALSE.
652  * The refcount of the new list is set to 1.
653  * See item_copy() for "copyID".
654  * Returns NULL when out of memory.
655  */
656     list_T *
657 list_copy(list_T *orig, int deep, int copyID)
658 {
659     list_T	*copy;
660     listitem_T	*item;
661     listitem_T	*ni;
662 
663     if (orig == NULL)
664 	return NULL;
665 
666     copy = list_alloc();
667     if (copy != NULL)
668     {
669 	if (copyID != 0)
670 	{
671 	    /* Do this before adding the items, because one of the items may
672 	     * refer back to this list. */
673 	    orig->lv_copyID = copyID;
674 	    orig->lv_copylist = copy;
675 	}
676 	for (item = orig->lv_first; item != NULL && !got_int;
677 							 item = item->li_next)
678 	{
679 	    ni = listitem_alloc();
680 	    if (ni == NULL)
681 		break;
682 	    if (deep)
683 	    {
684 		if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL)
685 		{
686 		    vim_free(ni);
687 		    break;
688 		}
689 	    }
690 	    else
691 		copy_tv(&item->li_tv, &ni->li_tv);
692 	    list_append(copy, ni);
693 	}
694 	++copy->lv_refcount;
695 	if (item != NULL)
696 	{
697 	    list_unref(copy);
698 	    copy = NULL;
699 	}
700     }
701 
702     return copy;
703 }
704 
705 /*
706  * Remove items "item" to "item2" from list "l".
707  * Does not free the listitem or the value!
708  * This used to be called list_remove, but that conflicts with a Sun header
709  * file.
710  */
711     void
712 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
713 {
714     listitem_T	*ip;
715 
716     /* notify watchers */
717     for (ip = item; ip != NULL; ip = ip->li_next)
718     {
719 	--l->lv_len;
720 	list_fix_watch(l, ip);
721 	if (ip == item2)
722 	    break;
723     }
724 
725     if (item2->li_next == NULL)
726 	l->lv_last = item->li_prev;
727     else
728 	item2->li_next->li_prev = item->li_prev;
729     if (item->li_prev == NULL)
730 	l->lv_first = item2->li_next;
731     else
732 	item->li_prev->li_next = item2->li_next;
733     l->lv_idx_item = NULL;
734 }
735 
736 /*
737  * Return an allocated string with the string representation of a list.
738  * May return NULL.
739  */
740     char_u *
741 list2string(typval_T *tv, int copyID, int restore_copyID)
742 {
743     garray_T	ga;
744 
745     if (tv->vval.v_list == NULL)
746 	return NULL;
747     ga_init2(&ga, (int)sizeof(char), 80);
748     ga_append(&ga, '[');
749     if (list_join(&ga, tv->vval.v_list, (char_u *)", ",
750 				       FALSE, restore_copyID, copyID) == FAIL)
751     {
752 	vim_free(ga.ga_data);
753 	return NULL;
754     }
755     ga_append(&ga, ']');
756     ga_append(&ga, NUL);
757     return (char_u *)ga.ga_data;
758 }
759 
760 typedef struct join_S {
761     char_u	*s;
762     char_u	*tofree;
763 } join_T;
764 
765     static int
766 list_join_inner(
767     garray_T	*gap,		/* to store the result in */
768     list_T	*l,
769     char_u	*sep,
770     int		echo_style,
771     int		restore_copyID,
772     int		copyID,
773     garray_T	*join_gap)	/* to keep each list item string */
774 {
775     int		i;
776     join_T	*p;
777     int		len;
778     int		sumlen = 0;
779     int		first = TRUE;
780     char_u	*tofree;
781     char_u	numbuf[NUMBUFLEN];
782     listitem_T	*item;
783     char_u	*s;
784 
785     /* Stringify each item in the list. */
786     for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
787     {
788 	s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
789 				      echo_style, restore_copyID, !echo_style);
790 	if (s == NULL)
791 	    return FAIL;
792 
793 	len = (int)STRLEN(s);
794 	sumlen += len;
795 
796 	(void)ga_grow(join_gap, 1);
797 	p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
798 	if (tofree != NULL || s != numbuf)
799 	{
800 	    p->s = s;
801 	    p->tofree = tofree;
802 	}
803 	else
804 	{
805 	    p->s = vim_strnsave(s, len);
806 	    p->tofree = p->s;
807 	}
808 
809 	line_breakcheck();
810 	if (did_echo_string_emsg)  /* recursion error, bail out */
811 	    break;
812     }
813 
814     /* Allocate result buffer with its total size, avoid re-allocation and
815      * multiple copy operations.  Add 2 for a tailing ']' and NUL. */
816     if (join_gap->ga_len >= 2)
817 	sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
818     if (ga_grow(gap, sumlen + 2) == FAIL)
819 	return FAIL;
820 
821     for (i = 0; i < join_gap->ga_len && !got_int; ++i)
822     {
823 	if (first)
824 	    first = FALSE;
825 	else
826 	    ga_concat(gap, sep);
827 	p = ((join_T *)join_gap->ga_data) + i;
828 
829 	if (p->s != NULL)
830 	    ga_concat(gap, p->s);
831 	line_breakcheck();
832     }
833 
834     return OK;
835 }
836 
837 /*
838  * Join list "l" into a string in "*gap", using separator "sep".
839  * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
840  * Return FAIL or OK.
841  */
842     int
843 list_join(
844     garray_T	*gap,
845     list_T	*l,
846     char_u	*sep,
847     int		echo_style,
848     int		restore_copyID,
849     int		copyID)
850 {
851     garray_T	join_ga;
852     int		retval;
853     join_T	*p;
854     int		i;
855 
856     if (l->lv_len < 1)
857 	return OK; /* nothing to do */
858     ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
859     retval = list_join_inner(gap, l, sep, echo_style, restore_copyID,
860 							    copyID, &join_ga);
861 
862     /* Dispose each item in join_ga. */
863     if (join_ga.ga_data != NULL)
864     {
865 	p = (join_T *)join_ga.ga_data;
866 	for (i = 0; i < join_ga.ga_len; ++i)
867 	{
868 	    vim_free(p->tofree);
869 	    ++p;
870 	}
871 	ga_clear(&join_ga);
872     }
873 
874     return retval;
875 }
876 
877 /*
878  * "join()" function
879  */
880     void
881 f_join(typval_T *argvars, typval_T *rettv)
882 {
883     garray_T	ga;
884     char_u	*sep;
885 
886     if (argvars[0].v_type != VAR_LIST)
887     {
888 	emsg(_(e_listreq));
889 	return;
890     }
891     if (argvars[0].vval.v_list == NULL)
892 	return;
893     if (argvars[1].v_type == VAR_UNKNOWN)
894 	sep = (char_u *)" ";
895     else
896 	sep = tv_get_string_chk(&argvars[1]);
897 
898     rettv->v_type = VAR_STRING;
899 
900     if (sep != NULL)
901     {
902 	ga_init2(&ga, (int)sizeof(char), 80);
903 	list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0);
904 	ga_append(&ga, NUL);
905 	rettv->vval.v_string = (char_u *)ga.ga_data;
906     }
907     else
908 	rettv->vval.v_string = NULL;
909 }
910 
911 /*
912  * Allocate a variable for a List and fill it from "*arg".
913  * Return OK or FAIL.
914  */
915     int
916 get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
917 {
918     list_T	*l = NULL;
919     typval_T	tv;
920     listitem_T	*item;
921 
922     if (evaluate)
923     {
924 	l = list_alloc();
925 	if (l == NULL)
926 	    return FAIL;
927     }
928 
929     *arg = skipwhite(*arg + 1);
930     while (**arg != ']' && **arg != NUL)
931     {
932 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
933 	    goto failret;
934 	if (evaluate)
935 	{
936 	    item = listitem_alloc();
937 	    if (item != NULL)
938 	    {
939 		item->li_tv = tv;
940 		item->li_tv.v_lock = 0;
941 		list_append(l, item);
942 	    }
943 	    else
944 		clear_tv(&tv);
945 	}
946 
947 	if (**arg == ']')
948 	    break;
949 	if (**arg != ',')
950 	{
951 	    semsg(_("E696: Missing comma in List: %s"), *arg);
952 	    goto failret;
953 	}
954 	*arg = skipwhite(*arg + 1);
955     }
956 
957     if (**arg != ']')
958     {
959 	semsg(_("E697: Missing end of List ']': %s"), *arg);
960 failret:
961 	if (evaluate)
962 	    list_free(l);
963 	return FAIL;
964     }
965 
966     *arg = skipwhite(*arg + 1);
967     if (evaluate)
968 	rettv_list_set(rettv, l);
969 
970     return OK;
971 }
972 
973 /*
974  * Write "list" of strings to file "fd".
975  */
976     int
977 write_list(FILE *fd, list_T *list, int binary)
978 {
979     listitem_T	*li;
980     int		c;
981     int		ret = OK;
982     char_u	*s;
983 
984     for (li = list->lv_first; li != NULL; li = li->li_next)
985     {
986 	for (s = tv_get_string(&li->li_tv); *s != NUL; ++s)
987 	{
988 	    if (*s == '\n')
989 		c = putc(NUL, fd);
990 	    else
991 		c = putc(*s, fd);
992 	    if (c == EOF)
993 	    {
994 		ret = FAIL;
995 		break;
996 	    }
997 	}
998 	if (!binary || li->li_next != NULL)
999 	    if (putc('\n', fd) == EOF)
1000 	    {
1001 		ret = FAIL;
1002 		break;
1003 	    }
1004 	if (ret == FAIL)
1005 	{
1006 	    emsg(_(e_write));
1007 	    break;
1008 	}
1009     }
1010     return ret;
1011 }
1012 
1013 /*
1014  * Initialize a static list with 10 items.
1015  */
1016     void
1017 init_static_list(staticList10_T *sl)
1018 {
1019     list_T  *l = &sl->sl_list;
1020     int	    i;
1021 
1022     memset(sl, 0, sizeof(staticList10_T));
1023     l->lv_first = &sl->sl_items[0];
1024     l->lv_last = &sl->sl_items[9];
1025     l->lv_refcount = DO_NOT_FREE_CNT;
1026     l->lv_lock = VAR_FIXED;
1027     sl->sl_list.lv_len = 10;
1028 
1029     for (i = 0; i < 10; ++i)
1030     {
1031 	listitem_T *li = &sl->sl_items[i];
1032 
1033 	if (i == 0)
1034 	    li->li_prev = NULL;
1035 	else
1036 	    li->li_prev = li - 1;
1037 	if (i == 9)
1038 	    li->li_next = NULL;
1039 	else
1040 	    li->li_next = li + 1;
1041     }
1042 }
1043 
1044 /*
1045  * "list2str()" function
1046  */
1047     void
1048 f_list2str(typval_T *argvars, typval_T *rettv)
1049 {
1050     list_T	*l;
1051     listitem_T	*li;
1052     garray_T	ga;
1053     int		utf8 = FALSE;
1054 
1055     rettv->v_type = VAR_STRING;
1056     rettv->vval.v_string = NULL;
1057     if (argvars[0].v_type != VAR_LIST)
1058     {
1059 	emsg(_(e_invarg));
1060 	return;
1061     }
1062 
1063     l = argvars[0].vval.v_list;
1064     if (l == NULL)
1065 	return;  // empty list results in empty string
1066 
1067     if (argvars[1].v_type != VAR_UNKNOWN)
1068 	utf8 = (int)tv_get_number_chk(&argvars[1], NULL);
1069 
1070     ga_init2(&ga, 1, 80);
1071     if (has_mbyte || utf8)
1072     {
1073 	char_u	buf[MB_MAXBYTES + 1];
1074 	int	(*char2bytes)(int, char_u *);
1075 
1076 	if (utf8 || enc_utf8)
1077 	    char2bytes = utf_char2bytes;
1078 	else
1079 	    char2bytes = mb_char2bytes;
1080 
1081 	for (li = l->lv_first; li != NULL; li = li->li_next)
1082 	{
1083 	    buf[(*char2bytes)(tv_get_number(&li->li_tv), buf)] = NUL;
1084 	    ga_concat(&ga, buf);
1085 	}
1086 	ga_append(&ga, NUL);
1087     }
1088     else if (ga_grow(&ga, list_len(l) + 1) == OK)
1089     {
1090 	for (li = l->lv_first; li != NULL; li = li->li_next)
1091 	    ga_append(&ga, tv_get_number(&li->li_tv));
1092 	ga_append(&ga, NUL);
1093     }
1094 
1095     rettv->v_type = VAR_STRING;
1096     rettv->vval.v_string = ga.ga_data;
1097 }
1098 
1099     void
1100 list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
1101 {
1102     list_T	*l;
1103     listitem_T	*item, *item2;
1104     listitem_T	*li;
1105     int		error = FALSE;
1106     int		idx;
1107 
1108     if ((l = argvars[0].vval.v_list) == NULL
1109 			      || var_check_lock(l->lv_lock, arg_errmsg, TRUE))
1110 	return;
1111 
1112     idx = (long)tv_get_number_chk(&argvars[1], &error);
1113     if (error)
1114 	;		// type error: do nothing, errmsg already given
1115     else if ((item = list_find(l, idx)) == NULL)
1116 	semsg(_(e_listidx), idx);
1117     else
1118     {
1119 	if (argvars[2].v_type == VAR_UNKNOWN)
1120 	{
1121 	    /* Remove one item, return its value. */
1122 	    vimlist_remove(l, item, item);
1123 	    *rettv = item->li_tv;
1124 	    vim_free(item);
1125 	}
1126 	else
1127 	{
1128 	    // Remove range of items, return list with values.
1129 	    int end = (long)tv_get_number_chk(&argvars[2], &error);
1130 
1131 	    if (error)
1132 		;		// type error: do nothing
1133 	    else if ((item2 = list_find(l, end)) == NULL)
1134 		semsg(_(e_listidx), end);
1135 	    else
1136 	    {
1137 		int	    cnt = 0;
1138 
1139 		for (li = item; li != NULL; li = li->li_next)
1140 		{
1141 		    ++cnt;
1142 		    if (li == item2)
1143 			break;
1144 		}
1145 		if (li == NULL)  /* didn't find "item2" after "item" */
1146 		    emsg(_(e_invrange));
1147 		else
1148 		{
1149 		    vimlist_remove(l, item, item2);
1150 		    if (rettv_list_alloc(rettv) == OK)
1151 		    {
1152 			l = rettv->vval.v_list;
1153 			l->lv_first = item;
1154 			l->lv_last = item2;
1155 			item->li_prev = NULL;
1156 			item2->li_next = NULL;
1157 			l->lv_len = cnt;
1158 		    }
1159 		}
1160 	    }
1161 	}
1162     }
1163 }
1164 
1165 static int item_compare(const void *s1, const void *s2);
1166 static int item_compare2(const void *s1, const void *s2);
1167 
1168 /* struct used in the array that's given to qsort() */
1169 typedef struct
1170 {
1171     listitem_T	*item;
1172     int		idx;
1173 } sortItem_T;
1174 
1175 /* struct storing information about current sort */
1176 typedef struct
1177 {
1178     int		item_compare_ic;
1179     int		item_compare_numeric;
1180     int		item_compare_numbers;
1181 #ifdef FEAT_FLOAT
1182     int		item_compare_float;
1183 #endif
1184     char_u	*item_compare_func;
1185     partial_T	*item_compare_partial;
1186     dict_T	*item_compare_selfdict;
1187     int		item_compare_func_err;
1188     int		item_compare_keep_zero;
1189 } sortinfo_T;
1190 static sortinfo_T	*sortinfo = NULL;
1191 #define ITEM_COMPARE_FAIL 999
1192 
1193 /*
1194  * Compare functions for f_sort() and f_uniq() below.
1195  */
1196     static int
1197 item_compare(const void *s1, const void *s2)
1198 {
1199     sortItem_T  *si1, *si2;
1200     typval_T	*tv1, *tv2;
1201     char_u	*p1, *p2;
1202     char_u	*tofree1 = NULL, *tofree2 = NULL;
1203     int		res;
1204     char_u	numbuf1[NUMBUFLEN];
1205     char_u	numbuf2[NUMBUFLEN];
1206 
1207     si1 = (sortItem_T *)s1;
1208     si2 = (sortItem_T *)s2;
1209     tv1 = &si1->item->li_tv;
1210     tv2 = &si2->item->li_tv;
1211 
1212     if (sortinfo->item_compare_numbers)
1213     {
1214 	varnumber_T	v1 = tv_get_number(tv1);
1215 	varnumber_T	v2 = tv_get_number(tv2);
1216 
1217 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
1218     }
1219 
1220 #ifdef FEAT_FLOAT
1221     if (sortinfo->item_compare_float)
1222     {
1223 	float_T	v1 = tv_get_float(tv1);
1224 	float_T	v2 = tv_get_float(tv2);
1225 
1226 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
1227     }
1228 #endif
1229 
1230     /* tv2string() puts quotes around a string and allocates memory.  Don't do
1231      * that for string variables. Use a single quote when comparing with a
1232      * non-string to do what the docs promise. */
1233     if (tv1->v_type == VAR_STRING)
1234     {
1235 	if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric)
1236 	    p1 = (char_u *)"'";
1237 	else
1238 	    p1 = tv1->vval.v_string;
1239     }
1240     else
1241 	p1 = tv2string(tv1, &tofree1, numbuf1, 0);
1242     if (tv2->v_type == VAR_STRING)
1243     {
1244 	if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric)
1245 	    p2 = (char_u *)"'";
1246 	else
1247 	    p2 = tv2->vval.v_string;
1248     }
1249     else
1250 	p2 = tv2string(tv2, &tofree2, numbuf2, 0);
1251     if (p1 == NULL)
1252 	p1 = (char_u *)"";
1253     if (p2 == NULL)
1254 	p2 = (char_u *)"";
1255     if (!sortinfo->item_compare_numeric)
1256     {
1257 	if (sortinfo->item_compare_ic)
1258 	    res = STRICMP(p1, p2);
1259 	else
1260 	    res = STRCMP(p1, p2);
1261     }
1262     else
1263     {
1264 	double n1, n2;
1265 	n1 = strtod((char *)p1, (char **)&p1);
1266 	n2 = strtod((char *)p2, (char **)&p2);
1267 	res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
1268     }
1269 
1270     /* When the result would be zero, compare the item indexes.  Makes the
1271      * sort stable. */
1272     if (res == 0 && !sortinfo->item_compare_keep_zero)
1273 	res = si1->idx > si2->idx ? 1 : -1;
1274 
1275     vim_free(tofree1);
1276     vim_free(tofree2);
1277     return res;
1278 }
1279 
1280     static int
1281 item_compare2(const void *s1, const void *s2)
1282 {
1283     sortItem_T  *si1, *si2;
1284     int		res;
1285     typval_T	rettv;
1286     typval_T	argv[3];
1287     char_u	*func_name;
1288     partial_T	*partial = sortinfo->item_compare_partial;
1289     funcexe_T	funcexe;
1290 
1291     /* shortcut after failure in previous call; compare all items equal */
1292     if (sortinfo->item_compare_func_err)
1293 	return 0;
1294 
1295     si1 = (sortItem_T *)s1;
1296     si2 = (sortItem_T *)s2;
1297 
1298     if (partial == NULL)
1299 	func_name = sortinfo->item_compare_func;
1300     else
1301 	func_name = partial_name(partial);
1302 
1303     /* Copy the values.  This is needed to be able to set v_lock to VAR_FIXED
1304      * in the copy without changing the original list items. */
1305     copy_tv(&si1->item->li_tv, &argv[0]);
1306     copy_tv(&si2->item->li_tv, &argv[1]);
1307 
1308     rettv.v_type = VAR_UNKNOWN;		/* clear_tv() uses this */
1309     vim_memset(&funcexe, 0, sizeof(funcexe));
1310     funcexe.evaluate = TRUE;
1311     funcexe.partial = partial;
1312     funcexe.selfdict = sortinfo->item_compare_selfdict;
1313     res = call_func(func_name, -1, &rettv, 2, argv, &funcexe);
1314     clear_tv(&argv[0]);
1315     clear_tv(&argv[1]);
1316 
1317     if (res == FAIL)
1318 	res = ITEM_COMPARE_FAIL;
1319     else
1320 	res = (int)tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err);
1321     if (sortinfo->item_compare_func_err)
1322 	res = ITEM_COMPARE_FAIL;  /* return value has wrong type */
1323     clear_tv(&rettv);
1324 
1325     /* When the result would be zero, compare the pointers themselves.  Makes
1326      * the sort stable. */
1327     if (res == 0 && !sortinfo->item_compare_keep_zero)
1328 	res = si1->idx > si2->idx ? 1 : -1;
1329 
1330     return res;
1331 }
1332 
1333 /*
1334  * "sort()" or "uniq()" function
1335  */
1336     static void
1337 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
1338 {
1339     list_T	*l;
1340     listitem_T	*li;
1341     sortItem_T	*ptrs;
1342     sortinfo_T	*old_sortinfo;
1343     sortinfo_T	info;
1344     long	len;
1345     long	i;
1346 
1347     /* Pointer to current info struct used in compare function. Save and
1348      * restore the current one for nested calls. */
1349     old_sortinfo = sortinfo;
1350     sortinfo = &info;
1351 
1352     if (argvars[0].v_type != VAR_LIST)
1353 	semsg(_(e_listarg), sort ? "sort()" : "uniq()");
1354     else
1355     {
1356 	l = argvars[0].vval.v_list;
1357 	if (l == NULL || var_check_lock(l->lv_lock,
1358 	     (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")),
1359 									TRUE))
1360 	    goto theend;
1361 	rettv_list_set(rettv, l);
1362 
1363 	len = list_len(l);
1364 	if (len <= 1)
1365 	    goto theend;	/* short list sorts pretty quickly */
1366 
1367 	info.item_compare_ic = FALSE;
1368 	info.item_compare_numeric = FALSE;
1369 	info.item_compare_numbers = FALSE;
1370 #ifdef FEAT_FLOAT
1371 	info.item_compare_float = FALSE;
1372 #endif
1373 	info.item_compare_func = NULL;
1374 	info.item_compare_partial = NULL;
1375 	info.item_compare_selfdict = NULL;
1376 	if (argvars[1].v_type != VAR_UNKNOWN)
1377 	{
1378 	    /* optional second argument: {func} */
1379 	    if (argvars[1].v_type == VAR_FUNC)
1380 		info.item_compare_func = argvars[1].vval.v_string;
1381 	    else if (argvars[1].v_type == VAR_PARTIAL)
1382 		info.item_compare_partial = argvars[1].vval.v_partial;
1383 	    else
1384 	    {
1385 		int	    error = FALSE;
1386 
1387 		i = (long)tv_get_number_chk(&argvars[1], &error);
1388 		if (error)
1389 		    goto theend;	/* type error; errmsg already given */
1390 		if (i == 1)
1391 		    info.item_compare_ic = TRUE;
1392 		else if (argvars[1].v_type != VAR_NUMBER)
1393 		    info.item_compare_func = tv_get_string(&argvars[1]);
1394 		else if (i != 0)
1395 		{
1396 		    emsg(_(e_invarg));
1397 		    goto theend;
1398 		}
1399 		if (info.item_compare_func != NULL)
1400 		{
1401 		    if (*info.item_compare_func == NUL)
1402 		    {
1403 			/* empty string means default sort */
1404 			info.item_compare_func = NULL;
1405 		    }
1406 		    else if (STRCMP(info.item_compare_func, "n") == 0)
1407 		    {
1408 			info.item_compare_func = NULL;
1409 			info.item_compare_numeric = TRUE;
1410 		    }
1411 		    else if (STRCMP(info.item_compare_func, "N") == 0)
1412 		    {
1413 			info.item_compare_func = NULL;
1414 			info.item_compare_numbers = TRUE;
1415 		    }
1416 #ifdef FEAT_FLOAT
1417 		    else if (STRCMP(info.item_compare_func, "f") == 0)
1418 		    {
1419 			info.item_compare_func = NULL;
1420 			info.item_compare_float = TRUE;
1421 		    }
1422 #endif
1423 		    else if (STRCMP(info.item_compare_func, "i") == 0)
1424 		    {
1425 			info.item_compare_func = NULL;
1426 			info.item_compare_ic = TRUE;
1427 		    }
1428 		}
1429 	    }
1430 
1431 	    if (argvars[2].v_type != VAR_UNKNOWN)
1432 	    {
1433 		/* optional third argument: {dict} */
1434 		if (argvars[2].v_type != VAR_DICT)
1435 		{
1436 		    emsg(_(e_dictreq));
1437 		    goto theend;
1438 		}
1439 		info.item_compare_selfdict = argvars[2].vval.v_dict;
1440 	    }
1441 	}
1442 
1443 	/* Make an array with each entry pointing to an item in the List. */
1444 	ptrs = ALLOC_MULT(sortItem_T, len);
1445 	if (ptrs == NULL)
1446 	    goto theend;
1447 
1448 	i = 0;
1449 	if (sort)
1450 	{
1451 	    /* sort(): ptrs will be the list to sort */
1452 	    for (li = l->lv_first; li != NULL; li = li->li_next)
1453 	    {
1454 		ptrs[i].item = li;
1455 		ptrs[i].idx = i;
1456 		++i;
1457 	    }
1458 
1459 	    info.item_compare_func_err = FALSE;
1460 	    info.item_compare_keep_zero = FALSE;
1461 	    /* test the compare function */
1462 	    if ((info.item_compare_func != NULL
1463 					 || info.item_compare_partial != NULL)
1464 		    && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
1465 							 == ITEM_COMPARE_FAIL)
1466 		emsg(_("E702: Sort compare function failed"));
1467 	    else
1468 	    {
1469 		/* Sort the array with item pointers. */
1470 		qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T),
1471 		    info.item_compare_func == NULL
1472 					  && info.item_compare_partial == NULL
1473 					       ? item_compare : item_compare2);
1474 
1475 		if (!info.item_compare_func_err)
1476 		{
1477 		    /* Clear the List and append the items in sorted order. */
1478 		    l->lv_first = l->lv_last = l->lv_idx_item = NULL;
1479 		    l->lv_len = 0;
1480 		    for (i = 0; i < len; ++i)
1481 			list_append(l, ptrs[i].item);
1482 		}
1483 	    }
1484 	}
1485 	else
1486 	{
1487 	    int	(*item_compare_func_ptr)(const void *, const void *);
1488 
1489 	    /* f_uniq(): ptrs will be a stack of items to remove */
1490 	    info.item_compare_func_err = FALSE;
1491 	    info.item_compare_keep_zero = TRUE;
1492 	    item_compare_func_ptr = info.item_compare_func != NULL
1493 					  || info.item_compare_partial != NULL
1494 					       ? item_compare2 : item_compare;
1495 
1496 	    for (li = l->lv_first; li != NULL && li->li_next != NULL;
1497 							     li = li->li_next)
1498 	    {
1499 		if (item_compare_func_ptr((void *)&li, (void *)&li->li_next)
1500 									 == 0)
1501 		    ptrs[i++].item = li;
1502 		if (info.item_compare_func_err)
1503 		{
1504 		    emsg(_("E882: Uniq compare function failed"));
1505 		    break;
1506 		}
1507 	    }
1508 
1509 	    if (!info.item_compare_func_err)
1510 	    {
1511 		while (--i >= 0)
1512 		{
1513 		    li = ptrs[i].item->li_next;
1514 		    ptrs[i].item->li_next = li->li_next;
1515 		    if (li->li_next != NULL)
1516 			li->li_next->li_prev = ptrs[i].item;
1517 		    else
1518 			l->lv_last = ptrs[i].item;
1519 		    list_fix_watch(l, li);
1520 		    listitem_free(li);
1521 		    l->lv_len--;
1522 		}
1523 	    }
1524 	}
1525 
1526 	vim_free(ptrs);
1527     }
1528 theend:
1529     sortinfo = old_sortinfo;
1530 }
1531 
1532 /*
1533  * "sort({list})" function
1534  */
1535     void
1536 f_sort(typval_T *argvars, typval_T *rettv)
1537 {
1538     do_sort_uniq(argvars, rettv, TRUE);
1539 }
1540 
1541 /*
1542  * "uniq({list})" function
1543  */
1544     void
1545 f_uniq(typval_T *argvars, typval_T *rettv)
1546 {
1547     do_sort_uniq(argvars, rettv, FALSE);
1548 }
1549 
1550 #endif /* defined(FEAT_EVAL) */
1551