29 #define UTARRAY_VERSION 2.0.1 32 #define _UNUSED_ __attribute__ ((__unused__)) 42 #define oom() exit(-1) 45 typedef void (ctor_f)(
void *dst,
const void *src);
46 typedef void (dtor_f)(
void *elt);
47 typedef void (init_f)(
void *elt);
61 #define utarray_init(a,_icd) do { \ 62 memset(a,0,sizeof(UT_array)); \ 66 #define utarray_done(a) do { \ 68 if ((a)->icd.dtor) { \ 70 for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ 71 (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ 79 #define utarray_new(a,_icd) do { \ 80 (a) = (UT_array*)malloc(sizeof(UT_array)); \ 81 if ((a) == NULL) oom(); \ 82 utarray_init(a,_icd); \ 85 #define utarray_free(a) do { \ 90 #define utarray_reserve(a,by) do { \ 91 if (((a)->i+(by)) > (a)->n) { \ 93 while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ 94 utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \ 95 if (utarray_tmp == NULL) oom(); \ 100 #define utarray_push_back(a,p) do { \ 101 utarray_reserve(a,1); \ 102 if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \ 103 else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \ 106 #define utarray_pop_back(a) do { \ 107 if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \ 111 #define utarray_extend_back(a) do { \ 112 utarray_reserve(a,1); \ 113 if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \ 114 else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \ 118 #define utarray_len(a) ((a)->i) 120 #define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL) 121 #define _utarray_eltptr(a,j) ((a)->d + ((a)->icd.sz * (j))) 123 #define utarray_insert(a,p,j) do { \ 124 if ((j) > (a)->i) utarray_resize(a,j); \ 125 utarray_reserve(a,1); \ 126 if ((j) < (a)->i) { \ 127 memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \ 128 ((a)->i - (j))*((a)->icd.sz)); \ 130 if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \ 131 else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \ 135 #define utarray_inserta(a,w,j) do { \ 136 if (utarray_len(w) == 0) break; \ 137 if ((j) > (a)->i) utarray_resize(a,j); \ 138 utarray_reserve(a,utarray_len(w)); \ 139 if ((j) < (a)->i) { \ 140 memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \ 141 _utarray_eltptr(a,j), \ 142 ((a)->i - (j))*((a)->icd.sz)); \ 144 if ((a)->icd.copy) { \ 146 for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \ 147 (a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \ 150 memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \ 151 utarray_len(w)*((a)->icd.sz)); \ 153 (a)->i += utarray_len(w); \ 156 #define utarray_resize(dst,num) do { \ 158 if ((dst)->i > (unsigned)(num)) { \ 159 if ((dst)->icd.dtor) { \ 160 for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \ 161 (dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \ 164 } else if ((dst)->i < (unsigned)(num)) { \ 165 utarray_reserve(dst, (num) - (dst)->i); \ 166 if ((dst)->icd.init) { \ 167 for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \ 168 (dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \ 171 memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \ 177 #define utarray_concat(dst,src) do { \ 178 utarray_inserta(dst, src, utarray_len(dst)); \ 181 #define utarray_erase(a,pos,len) do { \ 182 if ((a)->icd.dtor) { \ 184 for (_ut_i = 0; _ut_i < (len); _ut_i++) { \ 185 (a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \ 188 if ((a)->i > ((pos) + (len))) { \ 189 memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \ 190 ((a)->i - ((pos) + (len))) * (a)->icd.sz); \ 195 #define utarray_renew(a,u) do { \ 196 if (a) utarray_clear(a); \ 197 else utarray_new(a, u); \ 200 #define utarray_clear(a) do { \ 202 if ((a)->icd.dtor) { \ 204 for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ 205 (a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \ 212 #define utarray_sort(a,cmp) do { \ 213 qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \ 216 #define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp) 218 #define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL) 219 #define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : ((((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) 220 #define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL)) 221 #define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL) 222 #define utarray_eltidx(a,e) (((char*)(e) >= (a)->d) ? (((char*)(e) - (a)->d)/(a)->icd.sz) : -1) 225 static void utarray_str_cpy(
void *dst,
const void *src) {
226 char **_src = (
char**)src, **_dst = (
char**)dst;
227 *_dst = (*_src == NULL) ? NULL : strdup(*_src);
229 static void utarray_str_dtor(
void *elt) {
230 char **eltc = (
char**)elt;
231 if (*eltc != NULL) free(*eltc);
233 static const UT_icd ut_str_icd _UNUSED_ = {
sizeof(
char*),NULL,utarray_str_cpy,utarray_str_dtor};
234 static const UT_icd ut_int_icd _UNUSED_ = {
sizeof(int),NULL,NULL,NULL};
235 static const UT_icd ut_ptr_icd _UNUSED_ = {
sizeof(
void*),NULL,NULL,NULL};