Mercurial > hg > th-libs
annotate th_util.c @ 68:29f9651465c6
Added a new memory allocator function, th_malloc0(size), which is the same as calloc(1, size).
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 15 Nov 2012 19:22:06 +0200 |
parents | 34d58b0f2d52 |
children | 029b3dea31ff |
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 |
66 | 4 * (C) Copyright 2002-2012 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 #include "th_util.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
9 #include <stdio.h> |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
10 |
4
67f4a4233372
Move defaults to header file.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
11 /* Default settings |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
12 */ |
10 | 13 static BOOL th_initialized = FALSE; |
60 | 14 int th_verbosityLevel = 2; |
15 char *th_prog_name = NULL, | |
16 *th_prog_desc = NULL, | |
17 *th_prog_version = NULL, | |
18 *th_prog_author = NULL, | |
19 *th_prog_license = NULL; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
20 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
21 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
22 /* 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
|
23 */ |
60 | 24 void th_init(char *name, char *desc, char *version, |
25 char *author, char *license) | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
26 { |
60 | 27 th_prog_name = name; |
28 th_prog_desc = desc; | |
29 th_prog_version = version; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
30 |
60 | 31 if (author) |
32 th_prog_author = author; | |
10 | 33 else |
34 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
|
35 |
60 | 36 if (license) |
37 th_prog_license = license; | |
10 | 38 else |
39 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
|
40 |
10 | 41 th_initialized = TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
42 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
43 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
44 |
64 | 45 void th_print_banner(FILE *outFile, const char *name, const char *usage) |
45
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
46 { |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
47 fprintf(outFile, |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
48 "\n%s v%s (%s)\n" |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
49 "%s\n" |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
50 "%s\n" |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
51 "Usage: %s %s\n", |
60 | 52 th_prog_name, th_prog_version, th_prog_desc, |
64 | 53 th_prog_author, th_prog_license, name, usage); |
45
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
54 } |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
55 |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
56 |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
57 /* 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
|
58 * 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
|
59 */ |
11 | 60 void THERR_V(const char *fmt, va_list ap) |
61 { | |
62 assert(th_initialized == TRUE); | |
63 | |
64 fprintf(stderr, "%s: ", th_prog_name); | |
65 vfprintf(stderr, fmt, ap); | |
66 } | |
67 | |
68 | |
69 void THMSG_V(int level, const char *fmt, va_list ap) | |
70 { | |
71 assert(th_initialized == TRUE); | |
72 | |
48 | 73 if (th_verbosityLevel >= level) |
74 { | |
11 | 75 fprintf(stderr, "%s: ", th_prog_name); |
76 vfprintf(stderr, fmt, ap); | |
77 } | |
78 } | |
79 | |
80 | |
81 void THPRINT_V(int level, const char *fmt, va_list ap) | |
82 { | |
83 assert(th_initialized == TRUE); | |
84 | |
48 | 85 if (th_verbosityLevel >= level) |
86 { | |
11 | 87 vfprintf(stderr, fmt, ap); |
88 } | |
89 } | |
90 | |
91 | |
92 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
|
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 THERR_V(fmt, ap); | |
10 | 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 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
|
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 THMSG_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 |
11 | 114 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
|
115 { |
10 | 116 va_list ap; |
11 | 117 assert(th_initialized == TRUE); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
118 |
11 | 119 va_start(ap, fmt); |
120 THPRINT_V(level, fmt, ap); | |
121 va_end(ap); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
122 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
123 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
124 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
125 /* Memory handling routines |
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 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
|
128 { |
10 | 129 return malloc(l); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
130 } |
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 |
68
29f9651465c6
Added a new memory allocator function, th_malloc0(size), which is the same as calloc(1, size).
Matti Hamalainen <ccr@tnsp.org>
parents:
66
diff
changeset
|
133 void *th_malloc0(size_t l) |
29f9651465c6
Added a new memory allocator function, th_malloc0(size), which is the same as calloc(1, size).
Matti Hamalainen <ccr@tnsp.org>
parents:
66
diff
changeset
|
134 { |
29f9651465c6
Added a new memory allocator function, th_malloc0(size), which is the same as calloc(1, size).
Matti Hamalainen <ccr@tnsp.org>
parents:
66
diff
changeset
|
135 return calloc(1, l); |
29f9651465c6
Added a new memory allocator function, th_malloc0(size), which is the same as calloc(1, size).
Matti Hamalainen <ccr@tnsp.org>
parents:
66
diff
changeset
|
136 } |
29f9651465c6
Added a new memory allocator function, th_malloc0(size), which is the same as calloc(1, size).
Matti Hamalainen <ccr@tnsp.org>
parents:
66
diff
changeset
|
137 |
29f9651465c6
Added a new memory allocator function, th_malloc0(size), which is the same as calloc(1, size).
Matti Hamalainen <ccr@tnsp.org>
parents:
66
diff
changeset
|
138 |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
139 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
|
140 { |
10 | 141 return calloc(n, l); |
0
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 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
144 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
145 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
|
146 { |
10 | 147 return realloc(p, l); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
148 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
149 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
150 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
151 void th_free(void *p) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
152 { |
10 | 153 /* Check for NULL pointers for portability due to some libc |
154 * implementations not handling free(NULL) too well. | |
155 */ | |
156 if (p) free(p); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
157 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
158 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
159 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
160 #ifndef HAVE_MEMSET |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
161 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
|
162 { |
10 | 163 unsigned char *dp = (unsigned char *) p; |
164 | |
165 while (n--) | |
166 *(dp++) = c; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
167 |
10 | 168 return p; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
169 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
170 #endif |
16 | 171 |
172 /* Doubly linked list handling | |
173 * | |
174 * In this implementation first node's prev points to last node of the list, | |
175 * and last node's next is NULL. This way we can semi-efficiently traverse to | |
176 * beginning and end of the list, assuming user does not do weird things. | |
177 */ | |
178 qlist_t * th_llist_new(void *data) | |
179 { | |
180 qlist_t *res = th_calloc(sizeof(qlist_t), 1); | |
181 res->data = data; | |
182 return res; | |
183 } | |
184 | |
185 void th_llist_free_func(qlist_t *list, void (*freefunc)(void *data)) | |
186 { | |
187 qlist_t *curr = list; | |
188 | |
40 | 189 while (curr != NULL) |
190 { | |
16 | 191 qlist_t *next = curr->next; |
192 if (freefunc != NULL && curr->data != NULL) | |
193 freefunc(curr->data); | |
194 th_free(curr); | |
195 curr = next; | |
196 } | |
197 } | |
198 | |
199 | |
200 void th_llist_free(qlist_t *list) | |
201 { | |
202 th_llist_free_func(list, NULL); | |
203 } | |
204 | |
53
2c90b33d3617
Add th_llist_append_node() and th_llist_prepend_node() to public header.
Matti Hamalainen <ccr@tnsp.org>
parents:
49
diff
changeset
|
205 |
16 | 206 void th_llist_append_node(qlist_t **list, qlist_t *node) |
207 { | |
40 | 208 if (*list != NULL) |
209 { | |
16 | 210 node->prev = (*list)->prev; |
211 (*list)->prev->next = node; | |
212 (*list)->prev = node; | |
213 (*list)->num++; | |
40 | 214 } |
215 else | |
216 { | |
16 | 217 *list = node; |
59 | 218 node->prev = node; |
16 | 219 (*list)->num = 1; |
220 } | |
221 | |
222 node->next = NULL; | |
223 } | |
224 | |
225 | |
226 qlist_t *th_llist_append(qlist_t **list, void *data) | |
227 { | |
228 qlist_t *node = th_llist_new(data); | |
229 | |
230 th_llist_append_node(list, node); | |
231 | |
232 return node; | |
233 } | |
234 | |
235 | |
236 void th_llist_prepend_node(qlist_t **list, qlist_t *node) | |
237 { | |
40 | 238 if (*list != NULL) |
239 { | |
16 | 240 node->prev = (*list)->prev; |
241 node->next = *list; | |
242 (*list)->prev = node; | |
243 node->num = (*list)->num + 1; | |
244 *list = node; | |
40 | 245 } |
246 else | |
247 { | |
16 | 248 *list = node->prev = node; |
249 node->next = NULL; | |
250 (*list)->num = 1; | |
251 } | |
252 | |
253 } | |
254 | |
255 | |
256 qlist_t *th_llist_prepend(qlist_t **list, void *data) | |
257 { | |
258 qlist_t *node = th_llist_new(data); | |
259 | |
260 th_llist_prepend_node(list, node); | |
261 | |
262 return node; | |
263 } | |
264 | |
265 /* | |
266 1) Remove a middle node | |
267 | |
268 node0->prev->next = node->next (node1) | |
269 node0->next->prev = node->prev (list) | |
270 | |
271 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
272 node2 <- list <=> node1 <=> node2 -> NULL | |
273 | |
274 2) Remove first node when many items | |
275 | |
276 | |
277 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
278 node2 <- node0 <=> node1 <=> node2 -> NULL | |
279 | |
280 *list = node0 | |
281 | |
282 3) Remove last node in list | |
283 | |
284 if (node->next == NULL) { | |
285 list->prev = node->prev; | |
286 node->prev->next = NULL; | |
287 } | |
288 | |
289 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
290 node1 <- list <=> node0 <=> node1 -> NULL | |
291 | |
292 4) Remove last | |
293 | |
294 list <- list -> NULL | |
295 | |
296 | |
297 */ | |
298 static void th_llist_delete_node_fast(qlist_t **list, qlist_t *node) | |
299 { | |
40 | 300 if (node == *list) |
301 { | |
16 | 302 /* First node in list */ |
303 qlist_t *tmp = (*list)->next; | |
40 | 304 if (tmp != NULL) |
305 { | |
16 | 306 tmp->num = (*list)->num - 1; |
307 tmp->prev = (*list)->prev; | |
308 } | |
309 *list = tmp; | |
40 | 310 } |
311 else | |
312 { | |
16 | 313 /* Somewhere in middle or end */ |
314 if (node->prev != NULL) | |
315 node->prev->next = node->next; | |
316 | |
317 if (node->next != NULL) | |
318 node->next->prev = node->prev; | |
319 else | |
320 (*list)->prev = node; /* Last node */ | |
321 | |
322 (*list)->num--; | |
323 } | |
324 | |
325 node->next = node->prev = NULL; | |
326 } | |
327 | |
328 | |
329 void th_llist_delete_node(qlist_t **list, qlist_t *node) | |
330 { | |
331 qlist_t *curr = *list; | |
332 | |
40 | 333 while (curr != NULL) |
334 { | |
16 | 335 qlist_t *next = curr->next; |
40 | 336 if (curr == node) |
337 { | |
16 | 338 th_llist_delete_node_fast(list, curr); |
339 th_free(node); | |
340 break; | |
341 } | |
342 curr = next; | |
343 } | |
344 } | |
345 | |
346 | |
347 void th_llist_delete(qlist_t **list, const void *data) | |
348 { | |
349 qlist_t *curr = *list; | |
350 | |
40 | 351 while (curr != NULL) |
352 { | |
16 | 353 qlist_t *next = curr->next; |
40 | 354 if (curr->data == data) |
355 { | |
16 | 356 th_llist_delete_node_fast(list, curr); |
357 th_free(curr); | |
358 break; | |
359 } | |
360 curr = next; | |
361 } | |
362 } | |
363 | |
364 | |
365 qlist_t * th_llist_get_nth(qlist_t *list, const size_t n) | |
366 { | |
367 qlist_t *curr = list; | |
368 size_t i; | |
369 | |
370 for (i = 0; curr != NULL && i < n; curr = curr->next, i++); | |
371 | |
372 return curr; | |
373 } | |
374 | |
375 | |
376 size_t th_llist_length(const qlist_t *list) | |
377 { | |
378 if (list == NULL) | |
379 return 0; | |
380 else | |
381 return list->num; | |
382 } | |
383 | |
384 | |
385 ssize_t th_llist_position(const qlist_t *list, const qlist_t *node) | |
386 { | |
387 const qlist_t *curr = list; | |
388 ssize_t i = 0; | |
389 | |
40 | 390 while (curr != NULL) |
391 { | |
16 | 392 if (curr == node) |
393 return i; | |
394 else | |
395 i++; | |
396 | |
397 curr = curr->next; | |
398 } | |
399 | |
400 return -1; | |
401 } | |
402 | |
403 | |
55
300fba04b7ad
Adjust the foreach linked list functions a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
54
diff
changeset
|
404 void th_llist_foreach(qlist_t *list, void (*func)(qlist_t *node, void *userdata), void *data) |
54
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
405 { |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
406 qlist_t *curr = list; |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
407 |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
408 while (curr != NULL) |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
409 { |
55
300fba04b7ad
Adjust the foreach linked list functions a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
54
diff
changeset
|
410 func(curr, data); |
54
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
411 curr = curr->next; |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
412 } |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
413 } |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
414 |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
415 |
55
300fba04b7ad
Adjust the foreach linked list functions a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
54
diff
changeset
|
416 int th_llist_foreach_cond(qlist_t *list, int (*func)(qlist_t *node, void *userdata), void *data, qlist_t **ret) |
54
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
417 { |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
418 qlist_t *curr = list; |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
419 |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
420 while (curr != NULL) |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
421 { |
55
300fba04b7ad
Adjust the foreach linked list functions a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
54
diff
changeset
|
422 int res = func(curr, data); |
54
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
423 if (res != 0) |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
424 { |
55
300fba04b7ad
Adjust the foreach linked list functions a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
54
diff
changeset
|
425 *ret = curr; |
300fba04b7ad
Adjust the foreach linked list functions a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
54
diff
changeset
|
426 return res; |
54
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
427 } |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
428 curr = curr->next; |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
429 } |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
430 |
55
300fba04b7ad
Adjust the foreach linked list functions a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
54
diff
changeset
|
431 return 0; |
54
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
432 } |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
433 |
48926b3ff598
Add new linked list handling functions: th_llist_foreach() and th_llist_foreach_cond()
Matti Hamalainen <ccr@tnsp.org>
parents:
53
diff
changeset
|
434 |
16 | 435 qlist_t * th_llist_find(qlist_t *list, const void *data) |
436 { | |
437 qlist_t *curr = list; | |
438 | |
40 | 439 while (curr != NULL) |
440 { | |
16 | 441 if (curr->data == data) |
442 return curr; | |
443 curr = curr->next; | |
444 } | |
445 | |
446 return NULL; | |
447 } | |
448 | |
449 | |
450 qlist_t * th_llist_find_func(qlist_t *list, const void *userdata, int (compare)(const void *, const void *)) | |
451 { | |
452 qlist_t *curr = list; | |
453 | |
40 | 454 while (curr != NULL) |
455 { | |
16 | 456 if (compare(curr->data, userdata) == 0) |
457 return curr; | |
458 curr = curr->next; | |
459 } | |
460 | |
461 return NULL; | |
462 } | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
463 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
464 |
26 | 465 /* |
466 * Ringbuffers | |
467 */ | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
468 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
|
469 { |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
470 qringbuf_t *res = th_calloc(1, sizeof(qringbuf_t)); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
471 |
33 | 472 res->data = (char **) th_calloc(size, sizeof(char *)); |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
473 res->size = size; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
474 res->n = 0; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
475 res->deallocator = mdeallocator; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
476 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
477 return res; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
478 } |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
479 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
480 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
481 BOOL th_ringbuf_grow(qringbuf_t *buf, const size_t n) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
482 { |
33 | 483 buf->data = (char **) th_realloc(buf->data, (buf->size + n) * sizeof(char *)); |
40 | 484 if (buf->data != NULL) |
485 { | |
486 th_memset(buf->data + buf->size, 0, sizeof(char *) * n); | |
33 | 487 buf->size += n; |
488 return TRUE; | |
489 } else | |
490 return FALSE; | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
491 } |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
492 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
493 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
494 void th_ringbuf_free(qringbuf_t *buf) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
495 { |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
496 int i; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
497 |
33 | 498 for (i = 0; i < buf->size; i++) |
58
c12b66ec0362
Add braces, mostly cosmetic.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
499 { |
25
2f7270a9d593
Make ringbuffer deallocator function call only happen if data pointer is != NULL
Matti Hamalainen <ccr@tnsp.org>
parents:
23
diff
changeset
|
500 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
|
501 buf->deallocator(buf->data[i]); |
58
c12b66ec0362
Add braces, mostly cosmetic.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
502 } |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
503 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
504 th_free(buf->data); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
505 th_free(buf); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
506 } |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
507 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
508 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
509 void th_ringbuf_add(qringbuf_t *buf, void *ptr) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
510 { |
28
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
511 if (buf->n < buf->size) |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
512 buf->n++; |
28
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
513 |
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
514 th_free(buf->data[0]); |
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
515 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
|
516 buf->data[buf->size - 1] = ptr; |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
517 } |