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