1 /* A set of expandable list utilities, implimented as macros. */
2 /* Copyright 2006 Graeme W. Gill */
3 
4 #ifndef _XLIST_H_
5 
6 #ifdef __cplusplus
7 	extern "C" {
8 #endif
9 
10 /* An expanding list structure */
11 #define XLIST(objtype, name)								\
12 struct {													\
13 	int no;					/* Number of items in list */	\
14 	int _no;				/* Allocated size of list */	\
15 	int objsz;				/* Size of object */			\
16 	objtype  *list;			/* list */						\
17 } name;
18 
19 /* Initialize the list */
20 #define XLIST_INIT(objtype, xlp) 		\
21 	((xlp)->no = (xlp)->_no = 0,		\
22 	 (xlp)->objsz = sizeof(objtype),	\
23 	 (xlp)->list = NULL					\
24 	)
25 
26 /* test if the list is empty */
27 #define IS_XLIST_EMPTY(xlp) \
28 	((xlp)->no == 0)
29 
30 /* Return the number of items in the list */
31 #define XLIST_NO(xlp) \
32 	((xlp)->no)
33 
34 /* Return the n'th item in the list */
35 #define XLIST_ITEM(xlp, n) \
36 	((xlp)->list[n])
37 
38 /* Add an item to the end of a list */
39 /* We call error() if malloc failes */
40 #define XLIST_ADD(xlp, obj) \
41 	{																			\
42 		if ((xlp)->_no <= 0) {													\
43 			(xlp)->_no = 10;													\
44 			if (((xlp)->list = malloc((xlp)->objsz * (xlp)->_no)) == NULL)		\
45 				error("XLIST malloc failed on %d items of size %d", (xlp)->objsz, (xlp)->_no);		\
46 		} else if ((xlp)->_no <= (xlp)->no) {									\
47 			(xlp)->_no *= 2;		\
48 			if (((xlp)->list = realloc((xlp)->list, (xlp)->objsz * (xlp)->_no)) == NULL) \
49 				error("XLIST realloc failed on %d items of size %d", (xlp)->objsz, (xlp)->_no);		\
50 		}																		\
51 		(xlp)->list[(xlp)->no++] = (obj);										\
52 	}
53 
54 /* Free up the list */
55 #define XLIST_FREE(xlp) \
56 		{ if ((xlp)->_no > 0) free((xlp)->list); }
57 
58 #ifdef __cplusplus
59 	}
60 #endif
61 
62 #define _XLIST_H_
63 #endif /* _XLIST_H_ */
64 
65