xref: /plan9/sys/src/cmd/sam/list.c (revision fe7781984ffc0fb4e6fe7bdd337c461cead20cdf)
1 #include "sam.h"
2 
3 /*
4  * Check that list has room for one more element.
5  */
6 static void
growlist(List * l,int esize)7 growlist(List *l, int esize)
8 {
9 	uchar *p;
10 
11 	if(l->listptr == nil || l->nalloc == 0){
12 		l->nalloc = INCR;
13 		l->listptr = emalloc(INCR*esize);
14 		l->nused = 0;
15 	}
16 	else if(l->nused == l->nalloc){
17 		p = erealloc(l->listptr, (l->nalloc+INCR)*esize);
18 		l->listptr = p;
19 		memset(p+l->nalloc*esize, 0, INCR*esize);
20 		l->nalloc += INCR;
21 	}
22 }
23 
24 /*
25  * Remove the ith element from the list
26  */
27 void
dellist(List * l,int i)28 dellist(List *l, int i)
29 {
30 	Posn *pp;
31 	void **vpp;
32 
33 	l->nused--;
34 
35 	switch(l->type){
36 	case 'P':
37 		pp = l->posnptr+i;
38 		memmove(pp, pp+1, (l->nused-i)*sizeof(*pp));
39 		break;
40 	case 'p':
41 		vpp = l->voidpptr+i;
42 		memmove(vpp, vpp+1, (l->nused-i)*sizeof(*vpp));
43 		break;
44 	}
45 }
46 
47 /*
48  * Add a new element, whose position is i, to the list
49  */
50 void
inslist(List * l,int i,...)51 inslist(List *l, int i, ...)
52 {
53 	Posn *pp;
54 	void **vpp;
55 	va_list list;
56 
57 
58 	va_start(list, i);
59 	switch(l->type){
60 	case 'P':
61 		growlist(l, sizeof(*pp));
62 		pp = l->posnptr+i;
63 		memmove(pp+1, pp, (l->nused-i)*sizeof(*pp));
64 		*pp = va_arg(list, Posn);
65 		break;
66 	case 'p':
67 		growlist(l, sizeof(*vpp));
68 		vpp = l->voidpptr+i;
69 		memmove(vpp+1, vpp, (l->nused-i)*sizeof(*vpp));
70 		*vpp = va_arg(list, void*);
71 		break;
72 	}
73 	va_end(list);
74 
75 	l->nused++;
76 }
77 
78 void
listfree(List * l)79 listfree(List *l)
80 {
81 	free(l->listptr);
82 	free(l);
83 }
84 
85 List*
listalloc(int type)86 listalloc(int type)
87 {
88 	List *l;
89 
90 	l = emalloc(sizeof(List));
91 	l->type = type;
92 	l->nalloc = 0;
93 	l->nused = 0;
94 
95 	return l;
96 }
97