1 /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
2 See the COPYRIGHT file for more information. */
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include "includes.h"
7
listnull(void * e)8 int listnull(void* e) {return e == NULL;}
9
10 #ifndef TRUE
11 #define TRUE 1
12 #endif
13 #ifndef FALSE
14 #define FALSE 0
15 #endif
16
17 #define DEFAULTALLOC 16
18 #define ALLOCINCR 16
19
listnew(void)20 List* listnew(void)
21 {
22 List* l;
23 /*
24 if(!initialized) {
25 memset((void*)&DATANULL,0,sizeof(void*));
26 initialized = 1;
27 }
28 */
29 l = (List*)emalloc(sizeof(List));
30 if(l) {
31 l->alloc=0;
32 l->length=0;
33 l->content=NULL;
34 }
35 return l;
36 }
37
38 int
listfree(List * l)39 listfree(List* l)
40 {
41 if(l) {
42 l->alloc = 0;
43 if(l->content != NULL) {efree(l->content); l->content = NULL;}
44 efree(l);
45 }
46 return TRUE;
47 }
48
49 int
listsetalloc(List * l,unsigned long sz)50 listsetalloc(List* l, unsigned long sz)
51 {
52 void** newcontent = NULL;
53 if(l == NULL) return FALSE;
54 if(sz <= 0) {sz = (l->length?2*l->length:DEFAULTALLOC);}
55 if(l->alloc >= sz) {return TRUE;}
56 newcontent=(void**)ecalloc(sz*sizeof(void*));
57 if(newcontent != NULL && l->alloc > 0 && l->length > 0 && l->content != NULL) {
58 memcpy((void*)newcontent,(void*)l->content,sizeof(void*)*l->length);
59 }
60 if(l->content != NULL) efree(l->content);
61 l->content=newcontent;
62 l->alloc=sz;
63 return TRUE;
64 }
65
66 int
listsetlength(List * l,unsigned long sz)67 listsetlength(List* l, unsigned long sz)
68 {
69 if(l == NULL) return FALSE;
70 if(sz > l->alloc && !listsetalloc(l,sz)) return FALSE;
71 l->length = sz;
72 return TRUE;
73 }
74
75 void*
listget(List * l,unsigned long index)76 listget(List* l, unsigned long index)
77 {
78 if(l == NULL || l->length == 0) return NULL;
79 if(index >= l->length) return NULL;
80 return l->content[index];
81 }
82
83 int
listset(List * l,unsigned long index,void * elem)84 listset(List* l, unsigned long index, void* elem)
85 {
86 if(l == NULL) return FALSE;
87 if(index >= l->length) return FALSE;
88 l->content[index] = elem;
89 return TRUE;
90 }
91
92 /* Insert at position i of l; will push up elements i..|seq|. */
93 int
listinsert(List * l,unsigned long index,void * elem)94 listinsert(List* l, unsigned long index, void* elem)
95 {
96 int i; /* do not make unsigned */
97 if(l == NULL) return FALSE;
98 if(index > l->length) return FALSE;
99 listsetalloc(l,0);
100 for(i=(int)l->length;i>index;i--) l->content[i] = l->content[i-1];
101 l->content[index] = elem;
102 l->length++;
103 return TRUE;
104 }
105
106 int
listpush(List * l,void * elem)107 listpush(List* l, void* elem)
108 {
109 if(l == NULL) return FALSE;
110 if(l->length >= l->alloc) listsetalloc(l,0);
111 l->content[l->length] = elem;
112 l->length++;
113 return TRUE;
114 }
115
116 void*
listpop(List * l)117 listpop(List* l)
118 {
119 if(l == NULL || l->length == 0) return NULL;
120 l->length--;
121 return l->content[l->length];
122 }
123
124 void*
listtop(List * l)125 listtop(List* l)
126 {
127 if(l == NULL || l->length == 0) return NULL;
128 return l->content[l->length - 1];
129 }
130
131 void*
listremove(List * l,unsigned long i)132 listremove(List* l, unsigned long i)
133 {
134 unsigned long len;
135 void* elem;
136 if(l == NULL || (len=l->length) == 0) return NULL;
137 if(i >= len) return NULL;
138 elem = l->content[i];
139 for(i+=1;i<len;i++) l->content[i-1] = l->content[i];
140 l->length--;
141 return elem;
142 }
143
144 /* Duplicate and return the content (null terminate) */
145 void**
listdup(List * l)146 listdup(List* l)
147 {
148 void** result = (void**)emalloc(sizeof(void*)*(l->length+1));
149 memcpy((void*)result,(void*)l->content,sizeof(void*)*l->length);
150 result[l->length] = (void*)0;
151 return result;
152 }
153
154 int
listcontains(List * l,void * elem)155 listcontains(List* l, void* elem)
156 {
157 unsigned long i;
158 for(i=0;i<listlength(l);i++) {
159 if(elem == listget(l,i)) return 1;
160 }
161 return 0;
162 }
163
164 /* Remove element by value; only removes first encountered */
165 int
listelemremove(List * l,void * elem)166 listelemremove(List* l, void* elem)
167 {
168 unsigned long len;
169 unsigned long i;
170 int found = 0;
171 if(l == NULL || (len=l->length) == 0) return 0;
172 for(i=0;i<listlength(l);i++) {
173 void* candidate = l->content[i];
174 if(elem == candidate) {
175 for(i+=1;i<len;i++) l->content[i-1] = l->content[i];
176 l->length--;
177 found = 1;
178 break;
179 }
180 }
181 return found;
182 }
183
184
185
186
187 /* Extends list to include a unique operator
188 which remove duplicate values; NULL values removed
189 return value is always 1.
190 */
191
192 int
listunique(List * l)193 listunique(List* l)
194 {
195 unsigned long i,j,k,len;
196 void** content;
197 if(l == NULL || l->length == 0) return 1;
198 len = l->length;
199 content = l->content;
200 for(i=0;i<len;i++) {
201 for(j=i+1;j<len;j++) {
202 if(content[i] == content[j]) {
203 /* compress out jth element */
204 for(k=j+1;k<len;k++) content[k-1] = content[k];
205 len--;
206 }
207 }
208 }
209 l->length = len;
210 return 1;
211 }
212
213 List*
listclone(List * l)214 listclone(List* l)
215 {
216 List* clone = listnew();
217 *clone = *l;
218 clone->content = listdup(l);
219 return clone;
220 }
221