xref: /vim-8.2.3635/src/list.c (revision 723d165c)
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 = (list_T *)alloc_clear(sizeof(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((long_u)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((long_u)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
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 (listitem_T *)alloc(sizeof(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  * Allocate a variable for a List and fill it from "*arg".
879  * Return OK or FAIL.
880  */
881     int
882 get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
883 {
884     list_T	*l = NULL;
885     typval_T	tv;
886     listitem_T	*item;
887 
888     if (evaluate)
889     {
890 	l = list_alloc();
891 	if (l == NULL)
892 	    return FAIL;
893     }
894 
895     *arg = skipwhite(*arg + 1);
896     while (**arg != ']' && **arg != NUL)
897     {
898 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
899 	    goto failret;
900 	if (evaluate)
901 	{
902 	    item = listitem_alloc();
903 	    if (item != NULL)
904 	    {
905 		item->li_tv = tv;
906 		item->li_tv.v_lock = 0;
907 		list_append(l, item);
908 	    }
909 	    else
910 		clear_tv(&tv);
911 	}
912 
913 	if (**arg == ']')
914 	    break;
915 	if (**arg != ',')
916 	{
917 	    semsg(_("E696: Missing comma in List: %s"), *arg);
918 	    goto failret;
919 	}
920 	*arg = skipwhite(*arg + 1);
921     }
922 
923     if (**arg != ']')
924     {
925 	semsg(_("E697: Missing end of List ']': %s"), *arg);
926 failret:
927 	if (evaluate)
928 	    list_free(l);
929 	return FAIL;
930     }
931 
932     *arg = skipwhite(*arg + 1);
933     if (evaluate)
934 	rettv_list_set(rettv, l);
935 
936     return OK;
937 }
938 
939 /*
940  * Write "list" of strings to file "fd".
941  */
942     int
943 write_list(FILE *fd, list_T *list, int binary)
944 {
945     listitem_T	*li;
946     int		c;
947     int		ret = OK;
948     char_u	*s;
949 
950     for (li = list->lv_first; li != NULL; li = li->li_next)
951     {
952 	for (s = tv_get_string(&li->li_tv); *s != NUL; ++s)
953 	{
954 	    if (*s == '\n')
955 		c = putc(NUL, fd);
956 	    else
957 		c = putc(*s, fd);
958 	    if (c == EOF)
959 	    {
960 		ret = FAIL;
961 		break;
962 	    }
963 	}
964 	if (!binary || li->li_next != NULL)
965 	    if (putc('\n', fd) == EOF)
966 	    {
967 		ret = FAIL;
968 		break;
969 	    }
970 	if (ret == FAIL)
971 	{
972 	    emsg(_(e_write));
973 	    break;
974 	}
975     }
976     return ret;
977 }
978 
979 /*
980  * Initialize a static list with 10 items.
981  */
982     void
983 init_static_list(staticList10_T *sl)
984 {
985     list_T  *l = &sl->sl_list;
986     int	    i;
987 
988     memset(sl, 0, sizeof(staticList10_T));
989     l->lv_first = &sl->sl_items[0];
990     l->lv_last = &sl->sl_items[9];
991     l->lv_refcount = DO_NOT_FREE_CNT;
992     l->lv_lock = VAR_FIXED;
993     sl->sl_list.lv_len = 10;
994 
995     for (i = 0; i < 10; ++i)
996     {
997 	listitem_T *li = &sl->sl_items[i];
998 
999 	if (i == 0)
1000 	    li->li_prev = NULL;
1001 	else
1002 	    li->li_prev = li - 1;
1003 	if (i == 9)
1004 	    li->li_next = NULL;
1005 	else
1006 	    li->li_next = li + 1;
1007     }
1008 }
1009 
1010 #endif /* defined(FEAT_EVAL) */
1011