2 This file is part of the software library CADLIB written by Conrad Ziesler
3 Copyright 2003, Conrad Ziesler, all rights reserved.
5 *************************
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* list.c list module, for array-type list operators
29 /* listx, supports allocation and freeing of list elements */
31 void listx_init(listx_t
*l
, int size
, int mode
)
33 list_init(&(l
->list
),size
,mode
);
37 int listx_alloc(listx_t
*l
)
42 cell
=list_nextz(&(l
->list
));
43 l
->bitmap
=bitlist_new(l
->list
.m
);
44 assert(l
->bitmap
!=NULL
);
45 bitlist_set(l
->bitmap
,cell
);
50 cell
=bitlist_scan(l
->bitmap
,SCAN_FORWARD
|SCAN_CLEAR
);
51 if((cell
<0)||(cell
>=l
->list
.q
))
52 cell
=list_nextz(&(l
->list
));
54 if(l
->list
.m
!= l
->bitmap
->qty
)
55 l
->bitmap
=bitlist_resize(l
->bitmap
,l
->list
.m
);
57 bitlist_set(l
->bitmap
,cell
);
63 void listx_free(listx_t
*l
, int cell
)
65 bitlist_clear(l
->bitmap
,cell
);
66 memset(list_data(&(l
->list
),cell
),0,l
->list
.s
);
68 void listx_empty(listx_t
*l
)
70 list_empty(&(l
->list
));
71 if(l
->bitmap
!=NULL
)bitlist_free(l
->bitmap
);
75 void *listx_vdata(listx_t
*l
, int cell
)
77 if(bitlist_test(l
->bitmap
,cell
))
78 return list_data(&(l
->list
),cell
);
82 void *listx_data(listx_t
*l
, int cell
)
84 return list_data(&(l
->list
),cell
);
87 int listx_qty(listx_t
*l
)
89 return list_qty(&(l
->list
));
93 void list_shrink(list_t
*l
)
99 void list_empty(list_t
*l
)
108 void list_init(list_t
*l
, int s
, int mode
)
110 static const list_t id
=LIST_INITDATA
;
112 { *l
=id
; l
->s
=s
; l
->mode
=mode
; l
->q
=0; l
->m
=0; }
115 void list_hint(list_t
*l
, int max
)
129 l
->d
=realloc(l
->d
,(l
->m
=max
)*l
->s
);
136 void list_hint_grow(list_t
*l
, int add_q
)
140 l
->d
=realloc(l
->d
,(l
->m
=qm
)*l
->s
);
143 void inline *list_data_func(list_t
*l
, int i
)
146 return ((char *)(l
->d
))+(l
->s
* i
);
150 void *list_next(list_t
*l
)
156 if( (l
->mode
& LIST_FIXEDMODE
)!=0)
157 { assert(0); return NULL
; }
159 if( (l
->mode
& LIST_EXPMODE
)!=0)
163 if((l
->m
*l
->s
)>(1024*1024*16))
164 list_hint(l
,l
->m
+((1024*1024*16)/l
->s
));
166 list_hint(l
,2*( (l
->m
==0)?16:l
->m
) );
168 else list_hint(l
,l
->m
+1);
172 v
=l
->m
+(l
->mode
&LIST_MODECHUNK
);
177 return ((char *)(l
->d
))+(l
->s
* l
->q
++);
180 void *list_prev(list_t
*l
)
184 return ((char *)(l
->d
))+(l
->s
* --(l
->q
));
189 void *list_block_next(list_t
*l
, int qty
)
193 list_hint(l
, l
->q
+qty
);
195 r
=((char*)l
->d
)+(l
->s
*l
->q
);
203 int list_contains(list_t
*l
, void *d
)
207 if(memcmp(d
,list_data(l
,i
),l
->s
)==0)
212 int list_add(list_t
*l
, void *d
)
221 int list_nextz(list_t
*l
)
231 int list_index(list_t
*l
, void *p
)
233 if( p
>= (void *) ((((char *)(l
->d
))+(l
->s
*l
->q
)))) return -1;
234 if( p
< l
->d
) return -1;
235 return (((char *)p
)-((char *)(l
->d
)))/l
->s
;
238 int list_stdlib_bsearch(list_t
*l
, void *key
, int (*cmp
)(const void *a
, const void *b
))
240 void *p
= bsearch(key
,l
->d
, l
->q
,l
->s
,cmp
);
241 if(p
==NULL
)return -1;
242 return list_index(l
,p
);
245 void list_sort(list_t
*l
, int (*cmp
)(const void *a
, const void *b
))
247 qsort(l
->d
,l
->q
,l
->s
,cmp
);
250 void list_start(list_t
*l
)
256 int list_remove(list_t
*l
, int i
, void *save
)
262 if(save
!=NULL
)memcpy(save
,p
,l
->s
);
265 memmove(p
,((char *)p
)+l
->s
,(l
->q
-i
)*l
->s
);
270 void list_copyfrom(list_t
*newl
, list_t
*oldl
)
273 list_t id
=LIST_INITDATA
;
275 { *newl
=id
; newl
->s
=oldl
->s
; newl
->mode
=oldl
->mode
; newl
->q
=0; newl
->m
=0; }
278 void list_dup(list_t
*newl
, list_t
*oldl
)
281 list_copyfrom(newl
,oldl
);
282 list_hint(newl
,oldl
->q
);
283 d
=list_block_next(newl
,oldl
->q
);
284 memcpy(d
,oldl
->d
,oldl
->s
*oldl
->q
);
287 void list_append(list_t
*growing
, list_t
*copyfrom
)
290 if(copyfrom
==NULL
)return;
291 assert(growing
->s
==copyfrom
->s
);
292 if(copyfrom
->q
==0)return;
293 list_hint(growing
,growing
->q
+copyfrom
->q
);
294 d
=list_block_next(growing
,copyfrom
->q
);
295 memcpy(d
,copyfrom
->d
,copyfrom
->s
*copyfrom
->q
);
299 int list_element_dup(list_t
*l
, int from
, int to
)
302 if( (to
>l
->q
) || (to
<0) || (from
>=l
->q
) || (from
<0) )return 1;
303 if(to
==l
->q
) list_next(l
);
306 assert((a
!=NULL
)&&(b
!=NULL
));
311 void list_reset(list_t
*l
)
319 int list_bsearch(sort_func_t
*sf
, void *key
)
322 char *base
=sf
->tosort
->d
;
324 int size
=sf
->tosort
->s
;
326 if(size
==0)return -1;
327 if(sf
->tosort
->q
==0)return -1;
328 if(base
==NULL
)return -1;
332 u
= sf
->tosort
->q
-1 ;
334 res
= sf
->cmpf(sf
,key
,base
);
335 idx
= sf
->cmpf(sf
,key
,(void *)(((const char *)base
)+((u
-1)*size
)));
336 if(0)fprintf(stderr
,"list_bsearch, cmpf(e 0)=%i cmpf(e %i)=%i ",res
,u
-1,idx
);
341 p
= (void *) (((const char *) base
) + (idx
* size
));
342 res
= sf
->cmpf (sf
, key
, p
);
343 if (res
<= 0) /* if we happen to hit the element, pretend we overshot, we want the first element of key */
351 p
= (void *) (((const char *) base
) + (l
* size
));
352 res
= sf
->cmpf (sf
,key
, p
);
353 if(0)fprintf(stderr
," l=%i u=%i res=%i\n",l
,u
,res
);
358 if(0)fprintf(stderr
,"no elements\n");