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