Mercurial > hg > th-libs
annotate th_util.c @ 40:5b1e38a41bac
Cosmetic cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 02 Oct 2011 23:58:42 +0300 |
parents | 06a72c643460 |
children | e031a062b731 |
rev | line source |
---|---|
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
1 /* |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
2 * Generic utility-functions, macros and defaults |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
3 * Programmed and designed by Matti 'ccr' Hamalainen |
16 | 4 * (C) Copyright 2002-2010 Tecnic Software productions (TNSP) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
5 * |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
6 * Please read file 'COPYING' for information on license and distribution. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
7 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
8 #ifdef HAVE_CONFIG_H |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
9 #include "config.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
10 #endif |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
11 #include "th_util.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
12 #include <stdio.h> |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
13 |
4
67f4a4233372
Move defaults to header file.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
14 /* Default settings |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
15 */ |
10 | 16 static BOOL th_initialized = FALSE; |
17 int th_verbosityLevel = 2; | |
18 char *th_prog_name = NULL, | |
19 *th_prog_fullname = NULL, | |
20 *th_prog_version = NULL, | |
21 *th_prog_author = NULL, | |
22 *th_prog_license = NULL; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
23 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
24 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
25 /* Initialize th_util-library and global variables |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
26 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
27 void th_init(char *progName, char *progFullName, char *progVersion, |
10 | 28 char *progAuthor, char *progLicense) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
29 { |
10 | 30 th_prog_name = progName; |
31 th_prog_fullname = progFullName; | |
32 th_prog_version = progVersion; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
33 |
10 | 34 if (progAuthor) |
35 th_prog_author = progAuthor; | |
36 else | |
37 th_prog_author = TH_PROG_AUTHOR; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
38 |
10 | 39 if (progLicense) |
40 th_prog_license = progLicense; | |
41 else | |
42 th_prog_license = TH_PROG_LICENSE; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
43 |
10 | 44 th_initialized = TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
45 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
46 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
47 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
48 /* Print formatted error, warning and information messages |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
49 * TODO: Implement th_vfprintf() and friends? |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
50 */ |
11 | 51 void THERR_V(const char *fmt, va_list ap) |
52 { | |
53 assert(th_initialized == TRUE); | |
54 | |
55 fprintf(stderr, "%s: ", th_prog_name); | |
56 vfprintf(stderr, fmt, ap); | |
57 } | |
58 | |
59 | |
60 void THMSG_V(int level, const char *fmt, va_list ap) | |
61 { | |
62 assert(th_initialized == TRUE); | |
63 | |
64 if (th_verbosityLevel >= level) { | |
65 fprintf(stderr, "%s: ", th_prog_name); | |
66 vfprintf(stderr, fmt, ap); | |
67 } | |
68 } | |
69 | |
70 | |
71 void THPRINT_V(int level, const char *fmt, va_list ap) | |
72 { | |
73 assert(th_initialized == TRUE); | |
74 | |
75 if (th_verbosityLevel >= level) { | |
76 vfprintf(stderr, fmt, ap); | |
77 } | |
78 } | |
79 | |
80 | |
81 void THERR(const char *fmt, ...) | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
82 { |
10 | 83 va_list ap; |
11 | 84 assert(th_initialized == TRUE); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
85 |
11 | 86 va_start(ap, fmt); |
87 THERR_V(fmt, ap); | |
10 | 88 va_end(ap); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
89 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
90 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
91 |
11 | 92 void THMSG(int level, const char *fmt, ...) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
93 { |
10 | 94 va_list ap; |
11 | 95 assert(th_initialized == TRUE); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
96 |
11 | 97 va_start(ap, fmt); |
98 THMSG_V(level, fmt, ap); | |
99 va_end(ap); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
100 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
101 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
102 |
11 | 103 void THPRINT(int level, const char *fmt, ...) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
104 { |
10 | 105 va_list ap; |
11 | 106 assert(th_initialized == TRUE); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
107 |
11 | 108 va_start(ap, fmt); |
109 THPRINT_V(level, fmt, ap); | |
110 va_end(ap); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
111 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
112 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
113 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
114 /* Memory handling routines |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
115 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
116 void *th_malloc(size_t l) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
117 { |
10 | 118 return malloc(l); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
119 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
120 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
121 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
122 void *th_calloc(size_t n, size_t l) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
123 { |
10 | 124 return calloc(n, l); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
125 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
126 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
127 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
128 void *th_realloc(void *p, size_t l) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
129 { |
10 | 130 return realloc(p, l); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
131 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
132 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
133 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
134 void th_free(void *p) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
135 { |
10 | 136 /* Check for NULL pointers for portability due to some libc |
137 * implementations not handling free(NULL) too well. | |
138 */ | |
139 if (p) free(p); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
140 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
141 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
142 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
143 #ifndef HAVE_MEMSET |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
144 void *th_memset(void *p, int c, size_t n) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
145 { |
10 | 146 unsigned char *dp = (unsigned char *) p; |
147 | |
148 while (n--) | |
149 *(dp++) = c; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
150 |
10 | 151 return p; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
152 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
153 #endif |
16 | 154 |
155 /* Doubly linked list handling | |
156 * | |
157 * In this implementation first node's prev points to last node of the list, | |
158 * and last node's next is NULL. This way we can semi-efficiently traverse to | |
159 * beginning and end of the list, assuming user does not do weird things. | |
160 */ | |
161 qlist_t * th_llist_new(void *data) | |
162 { | |
163 qlist_t *res = th_calloc(sizeof(qlist_t), 1); | |
164 res->data = data; | |
165 return res; | |
166 } | |
167 | |
168 void th_llist_free_func(qlist_t *list, void (*freefunc)(void *data)) | |
169 { | |
170 qlist_t *curr = list; | |
171 | |
40 | 172 while (curr != NULL) |
173 { | |
16 | 174 qlist_t *next = curr->next; |
175 if (freefunc != NULL && curr->data != NULL) | |
176 freefunc(curr->data); | |
177 th_free(curr); | |
178 curr = next; | |
179 } | |
180 } | |
181 | |
182 | |
183 void th_llist_free(qlist_t *list) | |
184 { | |
185 th_llist_free_func(list, NULL); | |
186 } | |
187 | |
188 void th_llist_append_node(qlist_t **list, qlist_t *node) | |
189 { | |
40 | 190 if (*list != NULL) |
191 { | |
16 | 192 node->prev = (*list)->prev; |
193 (*list)->prev->next = node; | |
194 (*list)->prev = node; | |
195 (*list)->num++; | |
40 | 196 } |
197 else | |
198 { | |
16 | 199 *list = node; |
200 node->prev = *list; | |
201 (*list)->num = 1; | |
202 } | |
203 | |
204 node->next = NULL; | |
205 } | |
206 | |
207 | |
208 qlist_t *th_llist_append(qlist_t **list, void *data) | |
209 { | |
210 qlist_t *node = th_llist_new(data); | |
211 | |
212 th_llist_append_node(list, node); | |
213 | |
214 return node; | |
215 } | |
216 | |
217 | |
218 void th_llist_prepend_node(qlist_t **list, qlist_t *node) | |
219 { | |
40 | 220 if (*list != NULL) |
221 { | |
16 | 222 node->prev = (*list)->prev; |
223 node->next = *list; | |
224 (*list)->prev = node; | |
225 node->num = (*list)->num + 1; | |
226 *list = node; | |
40 | 227 } |
228 else | |
229 { | |
16 | 230 *list = node->prev = node; |
231 node->next = NULL; | |
232 (*list)->num = 1; | |
233 } | |
234 | |
235 } | |
236 | |
237 | |
238 qlist_t *th_llist_prepend(qlist_t **list, void *data) | |
239 { | |
240 qlist_t *node = th_llist_new(data); | |
241 | |
242 th_llist_prepend_node(list, node); | |
243 | |
244 return node; | |
245 } | |
246 | |
247 /* | |
248 1) Remove a middle node | |
249 | |
250 node0->prev->next = node->next (node1) | |
251 node0->next->prev = node->prev (list) | |
252 | |
253 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
254 node2 <- list <=> node1 <=> node2 -> NULL | |
255 | |
256 2) Remove first node when many items | |
257 | |
258 | |
259 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
260 node2 <- node0 <=> node1 <=> node2 -> NULL | |
261 | |
262 *list = node0 | |
263 | |
264 3) Remove last node in list | |
265 | |
266 if (node->next == NULL) { | |
267 list->prev = node->prev; | |
268 node->prev->next = NULL; | |
269 } | |
270 | |
271 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
272 node1 <- list <=> node0 <=> node1 -> NULL | |
273 | |
274 4) Remove last | |
275 | |
276 list <- list -> NULL | |
277 | |
278 | |
279 */ | |
280 static void th_llist_delete_node_fast(qlist_t **list, qlist_t *node) | |
281 { | |
40 | 282 if (node == *list) |
283 { | |
16 | 284 /* First node in list */ |
285 qlist_t *tmp = (*list)->next; | |
40 | 286 if (tmp != NULL) |
287 { | |
16 | 288 tmp->num = (*list)->num - 1; |
289 tmp->prev = (*list)->prev; | |
290 } | |
291 *list = tmp; | |
40 | 292 } |
293 else | |
294 { | |
16 | 295 /* Somewhere in middle or end */ |
296 if (node->prev != NULL) | |
297 node->prev->next = node->next; | |
298 | |
299 if (node->next != NULL) | |
300 node->next->prev = node->prev; | |
301 else | |
302 (*list)->prev = node; /* Last node */ | |
303 | |
304 (*list)->num--; | |
305 } | |
306 | |
307 node->next = node->prev = NULL; | |
308 } | |
309 | |
310 | |
311 void th_llist_delete_node(qlist_t **list, qlist_t *node) | |
312 { | |
313 qlist_t *curr = *list; | |
314 | |
40 | 315 while (curr != NULL) |
316 { | |
16 | 317 qlist_t *next = curr->next; |
40 | 318 if (curr == node) |
319 { | |
16 | 320 th_llist_delete_node_fast(list, curr); |
321 th_free(node); | |
322 break; | |
323 } | |
324 curr = next; | |
325 } | |
326 } | |
327 | |
328 | |
329 void th_llist_delete(qlist_t **list, const void *data) | |
330 { | |
331 qlist_t *curr = *list; | |
332 | |
40 | 333 while (curr != NULL) |
334 { | |
16 | 335 qlist_t *next = curr->next; |
40 | 336 if (curr->data == data) |
337 { | |
16 | 338 th_llist_delete_node_fast(list, curr); |
339 th_free(curr); | |
340 break; | |
341 } | |
342 curr = next; | |
343 } | |
344 } | |
345 | |
346 | |
347 qlist_t * th_llist_get_nth(qlist_t *list, const size_t n) | |
348 { | |
349 qlist_t *curr = list; | |
350 size_t i; | |
351 | |
352 for (i = 0; curr != NULL && i < n; curr = curr->next, i++); | |
353 | |
354 return curr; | |
355 } | |
356 | |
357 | |
358 size_t th_llist_length(const qlist_t *list) | |
359 { | |
360 if (list == NULL) | |
361 return 0; | |
362 else | |
363 return list->num; | |
364 } | |
365 | |
366 | |
367 ssize_t th_llist_position(const qlist_t *list, const qlist_t *node) | |
368 { | |
369 const qlist_t *curr = list; | |
370 ssize_t i = 0; | |
371 | |
40 | 372 while (curr != NULL) |
373 { | |
16 | 374 if (curr == node) |
375 return i; | |
376 else | |
377 i++; | |
378 | |
379 curr = curr->next; | |
380 } | |
381 | |
382 return -1; | |
383 } | |
384 | |
385 | |
386 qlist_t * th_llist_find(qlist_t *list, const void *data) | |
387 { | |
388 qlist_t *curr = list; | |
389 | |
40 | 390 while (curr != NULL) |
391 { | |
16 | 392 if (curr->data == data) |
393 return curr; | |
394 curr = curr->next; | |
395 } | |
396 | |
397 return NULL; | |
398 } | |
399 | |
400 | |
401 qlist_t * th_llist_find_func(qlist_t *list, const void *userdata, int (compare)(const void *, const void *)) | |
402 { | |
403 qlist_t *curr = list; | |
404 | |
40 | 405 while (curr != NULL) |
406 { | |
16 | 407 if (compare(curr->data, userdata) == 0) |
408 return curr; | |
409 curr = curr->next; | |
410 } | |
411 | |
412 return NULL; | |
413 } | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
414 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
415 |
26 | 416 /* |
417 * Ringbuffers | |
418 */ | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
419 qringbuf_t * th_ringbuf_new(const size_t size, void (*mdeallocator)(void *data)) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
420 { |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
421 qringbuf_t *res = th_calloc(1, sizeof(qringbuf_t)); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
422 |
33 | 423 res->data = (char **) th_calloc(size, sizeof(char *)); |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
424 res->size = size; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
425 res->n = 0; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
426 res->deallocator = mdeallocator; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
427 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
428 return res; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
429 } |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
430 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
431 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
432 BOOL th_ringbuf_grow(qringbuf_t *buf, const size_t n) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
433 { |
33 | 434 buf->data = (char **) th_realloc(buf->data, (buf->size + n) * sizeof(char *)); |
40 | 435 if (buf->data != NULL) |
436 { | |
437 th_memset(buf->data + buf->size, 0, sizeof(char *) * n); | |
33 | 438 buf->size += n; |
439 return TRUE; | |
440 } else | |
441 return FALSE; | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
442 } |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
443 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
444 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
445 void th_ringbuf_free(qringbuf_t *buf) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
446 { |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
447 int i; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
448 |
33 | 449 for (i = 0; i < buf->size; i++) |
25
2f7270a9d593
Make ringbuffer deallocator function call only happen if data pointer is != NULL
Matti Hamalainen <ccr@tnsp.org>
parents:
23
diff
changeset
|
450 if (buf->data[i] != NULL) |
2f7270a9d593
Make ringbuffer deallocator function call only happen if data pointer is != NULL
Matti Hamalainen <ccr@tnsp.org>
parents:
23
diff
changeset
|
451 buf->deallocator(buf->data[i]); |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
452 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
453 th_free(buf->data); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
454 th_free(buf); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
455 } |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
456 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
457 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
458 void th_ringbuf_add(qringbuf_t *buf, void *ptr) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
459 { |
28
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
460 if (buf->n < buf->size) |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
461 buf->n++; |
28
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
462 |
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
463 th_free(buf->data[0]); |
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
464 memmove(&(buf->data[0]), &(buf->data[1]), (buf->size - 1) * sizeof(void *)); |
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
465 buf->data[buf->size - 1] = ptr; |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
466 } |