Mercurial > hg > th-libs
annotate th_util.c @ 48:55e36ec05881
Cosmetics.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 03 Oct 2011 15:39:42 +0300 |
parents | e031a062b731 |
children | 598609fb49b0 |
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 |
45
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
48 void th_print_banner(FILE *outFile, const char *binName, const char *progUsage) |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
49 { |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
50 fprintf(outFile, |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
51 "\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
|
52 "%s\n" |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
53 "%s\n" |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
54 "Usage: %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
|
55 th_prog_name, th_prog_version, th_prog_fullname, |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
56 th_prog_author, th_prog_license, binName, progUsage); |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
57 } |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
58 |
e031a062b731
Separate program "banner" printing from th_args_help() to th_print_banner().
Matti Hamalainen <ccr@tnsp.org>
parents:
40
diff
changeset
|
59 |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
60 /* 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
|
61 * 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
|
62 */ |
11 | 63 void THERR_V(const char *fmt, va_list ap) |
64 { | |
65 assert(th_initialized == TRUE); | |
66 | |
67 fprintf(stderr, "%s: ", th_prog_name); | |
68 vfprintf(stderr, fmt, ap); | |
69 } | |
70 | |
71 | |
72 void THMSG_V(int level, const char *fmt, va_list ap) | |
73 { | |
74 assert(th_initialized == TRUE); | |
75 | |
48 | 76 if (th_verbosityLevel >= level) |
77 { | |
11 | 78 fprintf(stderr, "%s: ", th_prog_name); |
79 vfprintf(stderr, fmt, ap); | |
80 } | |
81 } | |
82 | |
83 | |
84 void THPRINT_V(int level, const char *fmt, va_list ap) | |
85 { | |
86 assert(th_initialized == TRUE); | |
87 | |
48 | 88 if (th_verbosityLevel >= level) |
89 { | |
11 | 90 vfprintf(stderr, fmt, ap); |
91 } | |
92 } | |
93 | |
94 | |
95 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
|
96 { |
10 | 97 va_list ap; |
11 | 98 assert(th_initialized == TRUE); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
99 |
11 | 100 va_start(ap, fmt); |
101 THERR_V(fmt, ap); | |
10 | 102 va_end(ap); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
103 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
104 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
105 |
11 | 106 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
|
107 { |
10 | 108 va_list ap; |
11 | 109 assert(th_initialized == TRUE); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
110 |
11 | 111 va_start(ap, fmt); |
112 THMSG_V(level, fmt, ap); | |
113 va_end(ap); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
114 } |
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 |
11 | 117 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
|
118 { |
10 | 119 va_list ap; |
11 | 120 assert(th_initialized == TRUE); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
121 |
11 | 122 va_start(ap, fmt); |
123 THPRINT_V(level, fmt, ap); | |
124 va_end(ap); | |
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 /* Memory handling routines |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
129 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
130 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
|
131 { |
10 | 132 return malloc(l); |
0
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 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
135 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
136 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
|
137 { |
10 | 138 return calloc(n, l); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
139 } |
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 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
|
143 { |
10 | 144 return realloc(p, l); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
145 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
146 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
147 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
148 void th_free(void *p) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
149 { |
10 | 150 /* Check for NULL pointers for portability due to some libc |
151 * implementations not handling free(NULL) too well. | |
152 */ | |
153 if (p) free(p); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
154 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
155 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
156 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
157 #ifndef HAVE_MEMSET |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
158 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
|
159 { |
10 | 160 unsigned char *dp = (unsigned char *) p; |
161 | |
162 while (n--) | |
163 *(dp++) = c; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
164 |
10 | 165 return p; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
166 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
167 #endif |
16 | 168 |
169 /* Doubly linked list handling | |
170 * | |
171 * In this implementation first node's prev points to last node of the list, | |
172 * and last node's next is NULL. This way we can semi-efficiently traverse to | |
173 * beginning and end of the list, assuming user does not do weird things. | |
174 */ | |
175 qlist_t * th_llist_new(void *data) | |
176 { | |
177 qlist_t *res = th_calloc(sizeof(qlist_t), 1); | |
178 res->data = data; | |
179 return res; | |
180 } | |
181 | |
182 void th_llist_free_func(qlist_t *list, void (*freefunc)(void *data)) | |
183 { | |
184 qlist_t *curr = list; | |
185 | |
40 | 186 while (curr != NULL) |
187 { | |
16 | 188 qlist_t *next = curr->next; |
189 if (freefunc != NULL && curr->data != NULL) | |
190 freefunc(curr->data); | |
191 th_free(curr); | |
192 curr = next; | |
193 } | |
194 } | |
195 | |
196 | |
197 void th_llist_free(qlist_t *list) | |
198 { | |
199 th_llist_free_func(list, NULL); | |
200 } | |
201 | |
202 void th_llist_append_node(qlist_t **list, qlist_t *node) | |
203 { | |
40 | 204 if (*list != NULL) |
205 { | |
16 | 206 node->prev = (*list)->prev; |
207 (*list)->prev->next = node; | |
208 (*list)->prev = node; | |
209 (*list)->num++; | |
40 | 210 } |
211 else | |
212 { | |
16 | 213 *list = node; |
214 node->prev = *list; | |
215 (*list)->num = 1; | |
216 } | |
217 | |
218 node->next = NULL; | |
219 } | |
220 | |
221 | |
222 qlist_t *th_llist_append(qlist_t **list, void *data) | |
223 { | |
224 qlist_t *node = th_llist_new(data); | |
225 | |
226 th_llist_append_node(list, node); | |
227 | |
228 return node; | |
229 } | |
230 | |
231 | |
232 void th_llist_prepend_node(qlist_t **list, qlist_t *node) | |
233 { | |
40 | 234 if (*list != NULL) |
235 { | |
16 | 236 node->prev = (*list)->prev; |
237 node->next = *list; | |
238 (*list)->prev = node; | |
239 node->num = (*list)->num + 1; | |
240 *list = node; | |
40 | 241 } |
242 else | |
243 { | |
16 | 244 *list = node->prev = node; |
245 node->next = NULL; | |
246 (*list)->num = 1; | |
247 } | |
248 | |
249 } | |
250 | |
251 | |
252 qlist_t *th_llist_prepend(qlist_t **list, void *data) | |
253 { | |
254 qlist_t *node = th_llist_new(data); | |
255 | |
256 th_llist_prepend_node(list, node); | |
257 | |
258 return node; | |
259 } | |
260 | |
261 /* | |
262 1) Remove a middle node | |
263 | |
264 node0->prev->next = node->next (node1) | |
265 node0->next->prev = node->prev (list) | |
266 | |
267 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
268 node2 <- list <=> node1 <=> node2 -> NULL | |
269 | |
270 2) Remove first node when many items | |
271 | |
272 | |
273 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
274 node2 <- node0 <=> node1 <=> node2 -> NULL | |
275 | |
276 *list = node0 | |
277 | |
278 3) Remove last node in list | |
279 | |
280 if (node->next == NULL) { | |
281 list->prev = node->prev; | |
282 node->prev->next = NULL; | |
283 } | |
284 | |
285 node2 <- list <=> node0 <=> node1 <=> node2 -> NULL | |
286 node1 <- list <=> node0 <=> node1 -> NULL | |
287 | |
288 4) Remove last | |
289 | |
290 list <- list -> NULL | |
291 | |
292 | |
293 */ | |
294 static void th_llist_delete_node_fast(qlist_t **list, qlist_t *node) | |
295 { | |
40 | 296 if (node == *list) |
297 { | |
16 | 298 /* First node in list */ |
299 qlist_t *tmp = (*list)->next; | |
40 | 300 if (tmp != NULL) |
301 { | |
16 | 302 tmp->num = (*list)->num - 1; |
303 tmp->prev = (*list)->prev; | |
304 } | |
305 *list = tmp; | |
40 | 306 } |
307 else | |
308 { | |
16 | 309 /* Somewhere in middle or end */ |
310 if (node->prev != NULL) | |
311 node->prev->next = node->next; | |
312 | |
313 if (node->next != NULL) | |
314 node->next->prev = node->prev; | |
315 else | |
316 (*list)->prev = node; /* Last node */ | |
317 | |
318 (*list)->num--; | |
319 } | |
320 | |
321 node->next = node->prev = NULL; | |
322 } | |
323 | |
324 | |
325 void th_llist_delete_node(qlist_t **list, qlist_t *node) | |
326 { | |
327 qlist_t *curr = *list; | |
328 | |
40 | 329 while (curr != NULL) |
330 { | |
16 | 331 qlist_t *next = curr->next; |
40 | 332 if (curr == node) |
333 { | |
16 | 334 th_llist_delete_node_fast(list, curr); |
335 th_free(node); | |
336 break; | |
337 } | |
338 curr = next; | |
339 } | |
340 } | |
341 | |
342 | |
343 void th_llist_delete(qlist_t **list, const void *data) | |
344 { | |
345 qlist_t *curr = *list; | |
346 | |
40 | 347 while (curr != NULL) |
348 { | |
16 | 349 qlist_t *next = curr->next; |
40 | 350 if (curr->data == data) |
351 { | |
16 | 352 th_llist_delete_node_fast(list, curr); |
353 th_free(curr); | |
354 break; | |
355 } | |
356 curr = next; | |
357 } | |
358 } | |
359 | |
360 | |
361 qlist_t * th_llist_get_nth(qlist_t *list, const size_t n) | |
362 { | |
363 qlist_t *curr = list; | |
364 size_t i; | |
365 | |
366 for (i = 0; curr != NULL && i < n; curr = curr->next, i++); | |
367 | |
368 return curr; | |
369 } | |
370 | |
371 | |
372 size_t th_llist_length(const qlist_t *list) | |
373 { | |
374 if (list == NULL) | |
375 return 0; | |
376 else | |
377 return list->num; | |
378 } | |
379 | |
380 | |
381 ssize_t th_llist_position(const qlist_t *list, const qlist_t *node) | |
382 { | |
383 const qlist_t *curr = list; | |
384 ssize_t i = 0; | |
385 | |
40 | 386 while (curr != NULL) |
387 { | |
16 | 388 if (curr == node) |
389 return i; | |
390 else | |
391 i++; | |
392 | |
393 curr = curr->next; | |
394 } | |
395 | |
396 return -1; | |
397 } | |
398 | |
399 | |
400 qlist_t * th_llist_find(qlist_t *list, const void *data) | |
401 { | |
402 qlist_t *curr = list; | |
403 | |
40 | 404 while (curr != NULL) |
405 { | |
16 | 406 if (curr->data == data) |
407 return curr; | |
408 curr = curr->next; | |
409 } | |
410 | |
411 return NULL; | |
412 } | |
413 | |
414 | |
415 qlist_t * th_llist_find_func(qlist_t *list, const void *userdata, int (compare)(const void *, const void *)) | |
416 { | |
417 qlist_t *curr = list; | |
418 | |
40 | 419 while (curr != NULL) |
420 { | |
16 | 421 if (compare(curr->data, userdata) == 0) |
422 return curr; | |
423 curr = curr->next; | |
424 } | |
425 | |
426 return NULL; | |
427 } | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
428 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
429 |
26 | 430 /* |
431 * Ringbuffers | |
432 */ | |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
433 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
|
434 { |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
435 qringbuf_t *res = th_calloc(1, sizeof(qringbuf_t)); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
436 |
33 | 437 res->data = (char **) th_calloc(size, sizeof(char *)); |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
438 res->size = size; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
439 res->n = 0; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
440 res->deallocator = mdeallocator; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
441 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
442 return res; |
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 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
446 BOOL th_ringbuf_grow(qringbuf_t *buf, const size_t n) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
447 { |
33 | 448 buf->data = (char **) th_realloc(buf->data, (buf->size + n) * sizeof(char *)); |
40 | 449 if (buf->data != NULL) |
450 { | |
451 th_memset(buf->data + buf->size, 0, sizeof(char *) * n); | |
33 | 452 buf->size += n; |
453 return TRUE; | |
454 } else | |
455 return FALSE; | |
23
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 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
459 void th_ringbuf_free(qringbuf_t *buf) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
460 { |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
461 int i; |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
462 |
33 | 463 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
|
464 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
|
465 buf->deallocator(buf->data[i]); |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
466 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
467 th_free(buf->data); |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
468 th_free(buf); |
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 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
471 |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
472 void th_ringbuf_add(qringbuf_t *buf, void *ptr) |
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
473 { |
28
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
474 if (buf->n < buf->size) |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
475 buf->n++; |
28
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
476 |
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
477 th_free(buf->data[0]); |
c47dcb8a4ffe
Change how ringbuffer actually works to be more sensible.
Matti Hamalainen <ccr@tnsp.org>
parents:
27
diff
changeset
|
478 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
|
479 buf->data[buf->size - 1] = ptr; |
23
a4f894105953
Add ringbuffer implementation.
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
480 } |