EE445M RTOS
Taken at the University of Texas Spring 2015
utarray.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2008-2014, Troy D. Hanson http://troydhanson.github.com/uthash/
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10 
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
12 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
13 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
15 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 */
23 
24 /* a dynamic array implementation using macros
25  */
26 #ifndef UTARRAY_H
27 #define UTARRAY_H
28 
29 #define UTARRAY_VERSION 1.9.9
30 
31 #ifdef __GNUC__
32 #define _UNUSED_ __attribute__ ((__unused__))
33 #else
34 #define _UNUSED_
35 #endif
36 
37 #include <stddef.h> /* size_t */
38 #include <string.h> /* memset, etc */
39 #include <stdlib.h> /* exit */
40 
41 #define oom() exit(-1)
42 
43 typedef void (ctor_f)(void *dst, const void *src);
44 typedef void (dtor_f)(void *elt);
45 typedef void (init_f)(void *elt);
46 typedef struct {
47  size_t sz;
51 } UT_icd;
52 
53 typedef struct {
54  unsigned i,n;/* i: index of next available slot, n: num slots */
55  UT_icd icd; /* initializer, copy and destructor functions */
56  char *d; /* n slots of size icd->sz*/
57 } UT_array;
58 
59 #define utarray_init(a,_icd) do { \
60  memset(a,0,sizeof(UT_array)); \
61  (a)->icd=*_icd; \
62 } while(0)
63 
64 #define utarray_done(a) do { \
65  if ((a)->n) { \
66  if ((a)->icd.dtor) { \
67  size_t _ut_i; \
68  for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
69  (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \
70  } \
71  } \
72  free((a)->d); \
73  } \
74  (a)->n=0; \
75 } while(0)
76 
77 #define utarray_new(a,_icd) do { \
78  a=(UT_array*)malloc(sizeof(UT_array)); \
79  utarray_init(a,_icd); \
80 } while(0)
81 
82 #define utarray_free(a) do { \
83  utarray_done(a); \
84  free(a); \
85 } while(0)
86 
87 #define utarray_reserve(a,by) do { \
88  if (((a)->i+by) > ((a)->n)) { \
89  while(((a)->i+by) > ((a)->n)) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \
90  if ( ((a)->d=(char*)realloc((a)->d, (a)->n*(a)->icd.sz)) == NULL) oom(); \
91  } \
92 } while(0)
93 
94 #define utarray_push_back(a,p) do { \
95  utarray_reserve(a,1); \
96  if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \
97  else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \
98 } while(0)
99 
100 #define utarray_pop_back(a) do { \
101  if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \
102  else { (a)->i--; } \
103 } while(0)
104 
105 #define utarray_extend_back(a) do { \
106  utarray_reserve(a,1); \
107  if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \
108  else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \
109  (a)->i++; \
110 } while(0)
111 
112 #define utarray_len(a) ((a)->i)
113 
114 #define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL)
115 #define _utarray_eltptr(a,j) ((char*)((a)->d + ((a)->icd.sz*(j) )))
116 
117 #define utarray_insert(a,p,j) do { \
118  if (j > (a)->i) utarray_resize(a,j); \
119  utarray_reserve(a,1); \
120  if ((j) < (a)->i) { \
121  memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \
122  ((a)->i - (j))*((a)->icd.sz)); \
123  } \
124  if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \
125  else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \
126  (a)->i++; \
127 } while(0)
128 
129 #define utarray_inserta(a,w,j) do { \
130  if (utarray_len(w) == 0) break; \
131  if (j > (a)->i) utarray_resize(a,j); \
132  utarray_reserve(a,utarray_len(w)); \
133  if ((j) < (a)->i) { \
134  memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \
135  _utarray_eltptr(a,j), \
136  ((a)->i - (j))*((a)->icd.sz)); \
137  } \
138  if ((a)->icd.copy) { \
139  size_t _ut_i; \
140  for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \
141  (a)->icd.copy(_utarray_eltptr(a,j+_ut_i), _utarray_eltptr(w,_ut_i)); \
142  } \
143  } else { \
144  memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \
145  utarray_len(w)*((a)->icd.sz)); \
146  } \
147  (a)->i += utarray_len(w); \
148 } while(0)
149 
150 #define utarray_resize(dst,num) do { \
151  size_t _ut_i; \
152  if (dst->i > (size_t)(num)) { \
153  if ((dst)->icd.dtor) { \
154  for(_ut_i=num; _ut_i < dst->i; _ut_i++) { \
155  (dst)->icd.dtor(utarray_eltptr(dst,_ut_i)); \
156  } \
157  } \
158  } else if (dst->i < (size_t)(num)) { \
159  utarray_reserve(dst,num-dst->i); \
160  if ((dst)->icd.init) { \
161  for(_ut_i=dst->i; _ut_i < num; _ut_i++) { \
162  (dst)->icd.init(utarray_eltptr(dst,_ut_i)); \
163  } \
164  } else { \
165  memset(_utarray_eltptr(dst,dst->i),0,(dst)->icd.sz*(num-dst->i)); \
166  } \
167  } \
168  dst->i = num; \
169 } while(0)
170 
171 #define utarray_concat(dst,src) do { \
172  utarray_inserta((dst),(src),utarray_len(dst)); \
173 } while(0)
174 
175 #define utarray_erase(a,pos,len) do { \
176  if ((a)->icd.dtor) { \
177  size_t _ut_i; \
178  for(_ut_i=0; _ut_i < len; _ut_i++) { \
179  (a)->icd.dtor(utarray_eltptr((a),pos+_ut_i)); \
180  } \
181  } \
182  if ((a)->i > (pos+len)) { \
183  memmove( _utarray_eltptr((a),pos), _utarray_eltptr((a),pos+len), \
184  (((a)->i)-(pos+len))*((a)->icd.sz)); \
185  } \
186  (a)->i -= (len); \
187 } while(0)
188 
189 #define utarray_renew(a,u) do { \
190  if (a) utarray_clear(a); \
191  else utarray_new((a),(u)); \
192 } while(0)
193 
194 #define utarray_clear(a) do { \
195  if ((a)->i > 0) { \
196  if ((a)->icd.dtor) { \
197  size_t _ut_i; \
198  for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
199  (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \
200  } \
201  } \
202  (a)->i = 0; \
203  } \
204 } while(0)
205 
206 #define utarray_sort(a,cmp) do { \
207  qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \
208 } while(0)
209 
210 #define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp)
211 
212 #define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL)
213 #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))
214 #define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL))
215 #define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL)
216 #define utarray_eltidx(a,e) (((char*)(e) >= (char*)((a)->d)) ? (((char*)(e) - (char*)((a)->d))/(size_t)(a)->icd.sz) : -1)
217 
218 /* last we pre-define a few icd for common utarrays of ints and strings */
219 static void utarray_str_cpy(void *dst, const void *src) {
220  char **_src = (char**)src, **_dst = (char**)dst;
221  *_dst = (*_src == NULL) ? NULL : strdup(*_src);
222 }
223 static void utarray_str_dtor(void *elt) {
224  char **eltc = (char**)elt;
225  if (*eltc) free(*eltc);
226 }
228 static const UT_icd ut_int_icd _UNUSED_ = {sizeof(int),NULL,NULL,NULL};
229 static const UT_icd ut_ptr_icd _UNUSED_ = {sizeof(void*),NULL,NULL,NULL};
230 
231 
232 #endif /* UTARRAY_H */
void( init_f)(void *elt)
Definition: utarray.h:45
#define _UNUSED_
Definition: utarray.h:34
static void utarray_str_dtor(void *elt)
Definition: utarray.h:223
dtor_f * dtor
Definition: utarray.h:50
char * strdup(const char *str)
Definition: graphlib.c:15
static const UT_icd ut_str_icd
Definition: utarray.h:227
void( ctor_f)(void *dst, const void *src)
Definition: utarray.h:43
size_t sz
Definition: utarray.h:47
UT_icd icd
Definition: utarray.h:55
void( dtor_f)(void *elt)
Definition: utarray.h:44
ctor_f * copy
Definition: utarray.h:49
unsigned n
Definition: utarray.h:54
static const UT_icd ut_int_icd
Definition: utarray.h:228
char * d
Definition: utarray.h:56
init_f * init
Definition: utarray.h:48
static void utarray_str_cpy(void *dst, const void *src)
Definition: utarray.h:219
Definition: utarray.h:46
#define NULL
Definition: defines.h:32
static const UT_icd ut_ptr_icd
Definition: utarray.h:229