ekg2  GIT master
dynstuff_inline.h
Idź do dokumentacji tego pliku.
1 #ifndef __EKG_DYNSTUFF_INLINE_H
2 #define __EKG_DYNSTUFF_INLINE_H
3 
4 /* we could use typeof() instead of passing paramtype, but let's be more portable */
5 
6 #define DYNSTUFF_USE_LIST3 1
7 
8 #if DYNSTUFF_USE_LIST3
9 # include <ekg/dynstuff.h>
10 #endif
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #if DYNSTUFF_USE_LIST3
17 
18 #define __DYNSTUFF_LIST_ADD(lista, typ, __notused) \
19  void lista##_add(typ *new_) { list_add3((list_t *) (void *) &lista, (list_t) new_); }
20 
21 #define __DYNSTUFF_LIST_ADD_BEGINNING(lista, typ, __notused) \
22  void lista##_add(typ *new_) { list_add_beginning3((list_t *) (void *) &lista, (list_t) new_); }
23 
24 #define __DYNSTUFF_LIST_ADD_SORTED(lista, typ, comparision) \
25  void lista##_add(typ *new_) { list_add_sorted3((list_t *) (void *) &lista, (list_t) new_, (void *) comparision); }
26 
27 #define __DYNSTUFF_LIST_REMOVE_SAFE(lista, typ, free_func) \
28  void lista##_remove(typ *elem) { list_remove3((list_t *) (void *) &lista, (list_t) elem, (void *) free_func); }
29 
30 #define __DYNSTUFF_LIST_REMOVE_ITER(lista, typ, free_func) \
31  typ *lista##_removei(typ *elem) { return list_remove3i((list_t *) (void *) &lista, (list_t) elem, (void *) free_func); }
32 
33 #define __DYNSTUFF_LIST_UNLINK(lista, typ) \
34  void lista##_unlink(typ *elem) { list_unlink3((list_t *) (void *) &lista, (list_t) elem); }
35 
36 #define __DYNSTUFF_LIST_DESTROY(lista, typ, free_func) \
37  void lista##_destroy(void) { list_destroy3((list_t) lista, (void *) free_func); lista = NULL; }
38 
39 #define __DYNSTUFF_LIST_COUNT(lista, typ) \
40  int lista##_count(void) { return list_count((list_t) lista); }
41 
42 #else
43 
44 #define __DYNSTUFF_LIST_ADD(lista, typ, __notused) \
45  void lista##_add(typ *new_) { \
46  new_->next = NULL; \
47  if (!lista) { \
48  lista = new_; \
49  } else { \
50  typ *tmp = lista; \
51  \
52  while (tmp->next) \
53  tmp = tmp->next; \
54  tmp->next = new_; \
55  } \
56 }
57 
58 #define __DYNSTUFF_LIST_ADD_BEGINNING(lista, typ, __notused) \
59  void lista##_add(typ *new_) { \
60  new_->next = lista; \
61  lista = new_; \
62  }
63 
64 #define __DYNSTUFF_LIST_ADD_SORTED(lista, typ, comparision) \
65  void lista##_add(typ *new_) { \
66  new_->next = NULL; \
67  if (!lista) { \
68  lista = new_; \
69  } else { \
70  typ *tmp = lista; \
71  typ *prev = NULL; \
72  \
73  while (comparision(new_, tmp) > 0) { \
74  prev = tmp; \
75  tmp = tmp->next; \
76  if (!tmp) \
77  break; \
78  } \
79  \
80  if (!prev) { \
81  new_->next = lista; \
82  lista = new_; \
83  } else { \
84  prev->next = new_; \
85  new_->next = tmp; \
86  } \
87  } \
88  }
89 
90 #define __DYNSTUFF_LIST_REMOVE_SAFE(lista, typ, free_func) \
91  void lista##_remove(typ *elem) { \
92  if (!lista) /* programmer's fault */ \
93  return; \
94  \
95  if (lista == elem) \
96  lista = lista->next; \
97  else { \
98  typ *tmp, *last = lista; \
99  \
100  for (tmp = lista->next; tmp; tmp = tmp->next) { \
101  if (tmp == elem) \
102  break; \
103  if (tmp->next == NULL) { \
104  /* errno = ENOENT; */ \
105  return; \
106  } \
107  last = tmp; \
108  } \
109  last->next = tmp->next; \
110  } \
111  /* if (free_func) */ \
112  free_func(elem); \
113  xfree(elem); \
114  }
115 
116 #define __DYNSTUFF_LIST_REMOVE_ITER(lista, typ, free_func) \
117  typ *lista##_removei(typ *elem) { \
118  typ *ret; \
119  \
120  if (lista == elem) { \
121  lista = lista->next; \
122  ret = (typ *) &lista; \
123  } else { \
124  typ *tmp, *last = lista; \
125  \
126  for (tmp = lista->next; tmp; tmp = tmp->next) { \
127  if (tmp == elem) \
128  break; \
129  last = tmp; \
130  } \
131  last->next = tmp->next; \
132  ret = last; \
133  } \
134  /* if (free_func) */ \
135  free_func(elem); \
136  xfree(elem); \
137  return ret; \
138  }
139 
140 #define __DYNSTUFF_LIST_UNLINK(lista, typ) \
141  void lista##_unlink(typ *elem) { \
142  if (!lista) /* programmer's fault */ \
143  return; \
144  \
145  if (lista == elem) \
146  lista = lista->next; \
147  else { \
148  typ *tmp, *last = lista; \
149  \
150  for (tmp = lista->next; tmp; tmp = tmp->next) { \
151  if (tmp == elem) \
152  break; \
153  if (tmp->next == NULL) { \
154  /* errno = ENOENT; */ \
155  return; \
156  } \
157  last = tmp; \
158  } \
159  last->next = tmp->next; \
160  } \
161  }
162 
163 #define __DYNSTUFF_LIST_DESTROY(lista, typ, free_func) \
164  void lista##_destroy(void) { \
165  while (lista) { \
166  typ *tmp = lista; \
167  \
168  lista = lista->next; \
169  \
170  /* if (free_func) */ \
171  free_func(tmp); \
172  \
173  xfree(tmp); \
174  } \
175  }
176 
177 #define __DYNSTUFF_LIST_COUNT(lista, typ) \
178  int lista##_count(void) { \
179  int count = 0; \
180  typ *list; \
181  \
182  for (list = lista; list; list = list->next) \
183  count++; \
184  return count; \
185  }
186 
187 #endif /* !DYNSTUFF_USE_LIST3 */
188 
189 /* !!! for other lists !!! [when we (have many || don't know) head of list during compilation time] */
190 
191 #if DYNSTUFF_USE_LIST3
192 
193 #define __DYNSTUFF_ADD(prefix, typ, __notused) \
194  void prefix##_add(typ **lista, typ *new_) { list_add3((list_t *) lista, (list_t) new_); }
195 
196 #define __DYNSTUFF_ADD_BEGINNING(prefix, typ, __notused) \
197  void prefix##_add(typ **lista, typ *new_) { list_add_beginning3((list_t *) lista, (list_t) new_); }
198 
199 #define __DYNSTUFF_ADD_SORTED(prefix, typ, comparision) \
200  void prefix##_add(typ **lista, typ *new_) { list_add_sorted3((list_t *) lista, (list_t) new_, (void *) comparision); }
201 
202 #define __DYNSTUFF_REMOVE_SAFE(prefix, typ, free_func) \
203  void prefix##_remove(typ **lista, typ *elem) { \
204  list_remove3((list_t *) lista, (list_t) elem, (void *) free_func); \
205  }
206 
207 #define __DYNSTUFF_REMOVE_ITER(prefix, typ, free_func) \
208  typ *prefix##_removei(typ **lista, typ *elem) { \
209  return list_remove3i((list_t *) lista, (list_t) elem, (void *) free_func); \
210  }
211 
212 #define __DYNSTUFF_DESTROY(prefix, typ, free_func) \
213  void prefix##_destroy(typ **lista) { \
214  list_destroy3((list_t) *lista, (void *) free_func); \
215  *lista = NULL; \
216  }
217 
218 #define __DYNSTUFF_COUNT(prefix, typ) \
219  int prefix##_count(typ *lista) { \
220  return list_count((list_t) lista); \
221  }
222 
223 #define __DYNSTUFF_GET_NTH(prefix, typ) \
224  typ *prefix##_get_nth(typ *lista, int id) { \
225  return list_get_nth3((list_t) lista, id); \
226  }
227 
228 #else
229  /* XXX, checkit */
230 
231 #define __DYNSTUFF_ADD(prefix, typ, __notused) \
232  void prefix##_add(typ **lista, typ *new_) { \
233  typ *tmp = *lista; \
234  \
235  new_->next = NULL; \
236  if (!(tmp = *lista)) { \
237  *lista = new_; \
238  } else { \
239  while (tmp->next) \
240  tmp = tmp->next; \
241  tmp->next = new_; \
242  } \
243 }
244 
245 #define __DYNSTUFF_ADD_BEGINNING(prefix, typ, __notused) \
246  void prefix##_add(typ **lista, typ *new_) { \
247  new_->next = *lista; \
248  *lista = new_; \
249  }
250 
251 #define __DYNSTUFF_ADD_SORTED(prefix, typ, comparision) \
252  void prefix##_add(typ **lista, typ *new_) { \
253  typ *tmp; \
254  \
255  new_->next = NULL; \
256  if (!(tmp = *lista)) { \
257  *lista = new_; \
258  } else { \
259  typ *prev = NULL; \
260  \
261  while (comparision(new_, tmp) > 0) { \
262  prev = tmp; \
263  tmp = tmp->next; \
264  if (!tmp) \
265  break; \
266  } \
267  \
268  if (!prev) { \
269  new_->next = *lista; \
270  *lista = new_; \
271  } else { \
272  prev->next = new_; \
273  new_->next = tmp; \
274  } \
275  } \
276  }
277 
278 #define __DYNSTUFF_REMOVE_SAFE(prefix, typ, free_func) \
279  void prefix##_remove(typ **lista, typ *elem) { \
280  if (!lista || !(*lista)) /* programmer's fault */\
281  return; \
282  \
283  if (*lista == elem) \
284  *lista = (*lista)->next; \
285  else { \
286  typ *tmp, *last = *lista; \
287  \
288  for (tmp = (*lista)->next; tmp; tmp = tmp->next) { \
289  if (tmp == elem) \
290  break; \
291  if (tmp->next == NULL) { \
292  /* errno = ENOENT; */ \
293  return; \
294  } \
295  last = tmp; \
296  } \
297  last->next = tmp->next; \
298  } \
299  /* if (free_func) */ \
300  free_func(elem); \
301  xfree(elem); \
302  }
303 
304 #define __DYNSTUFF_REMOVE_ITER(prefix, typ, free_func) \
305  typ *prefix##_removei(typ **lista, typ *elem) { \
306  typ *ret; \
307  \
308  if (*lista == elem) { \
309  *lista = (*lista)->next; \
310  ret = (typ *) lista; \
311  } else { \
312  typ *tmp, *last = *lista; \
313  \
314  for (tmp = (*lista)->next; tmp; tmp = tmp->next) { \
315  if (tmp == elem) \
316  break; \
317  last = tmp; \
318  } \
319  last->next = tmp->next; \
320  ret = last; \
321  } \
322  /* if (free_func) */ \
323  free_func(elem); \
324  xfree(elem); \
325  return ret; \
326  }
327 
328 #define __DYNSTUFF_UNLINK(prefix, typ) \
329  void prefix##_unlink(typ **lista, typ *elem) { \
330  if (!lista || !(*lista)) /* programmer's fault */ \
331  return; \
332  \
333  if (*lista == elem) \
334  *lista = (*lista)->next; \
335  else { \
336  typ *tmp, *last = *lista; \
337  \
338  for (tmp = (*lista)->next; tmp; tmp = tmp->next) { \
339  if (tmp == elem) \
340  break; \
341  if (tmp->next == NULL) { \
342  /* errno = ENOENT; */ \
343  return; \
344  } \
345  last = tmp; \
346  } \
347  last->next = tmp->next; \
348  } \
349  }
350 
351 #define __DYNSTUFF_DESTROY(prefix, typ, free_func) \
352  void prefix##_destroy(typ **lista) { \
353  while (*lista) { \
354  typ *tmp = *lista; \
355  \
356  *lista = (*lista)->next; \
357  \
358  /* if (free_func) */ \
359  free_func(tmp); \
360  \
361  xfree(tmp); \
362  } \
363  }
364 
365 #define __DYNSTUFF_COUNT(prefix, typ) \
366  int prefix##_count(typ *list) { \
367  int count = 0; \
368  \
369  for (; list; list = list->next) \
370  count++; \
371  return count; \
372  }
373 
374 #define __DYNSTUFF_GET_NTH(prefix, typ) \
375  typ *prefix##_get_nth(typ *lista, int id) { \
376  while (lista) { \
377  if ((--id) == 0) \
378  return lista; \
379  \
380  lista = lista->next; \
381  } \
382  return NULL; \
383  }
384 
385 #endif
386 
387 #define __DYNSTUFF_NOREMOVE(lista, typ, free_func)
388 #define __DYNSTUFF_NOUNLINK(lista, typ)
389 #define __DYNSTUFF_NOCOUNT(lista, typ)
390 #define __DYNSTUFF_NODESTROY(lista, typ, free_func)
391 
392 #define DYNSTUFF_LIST_DECLARE_FULL(lista, type, compare_func, free_func, list_add, list_remove, list_remove2, list_unlink, list_destroy, list_count) \
393  list_add(lista, type, compare_func) \
394  list_remove(lista, type, free_func) \
395  list_remove2(lista, type, free_func) \
396  list_unlink(lista, type) \
397  list_destroy(lista, type, free_func) \
398  list_count(lista, type)
399 
400 #define DYNSTUFF_LIST_DECLARE(lista, type, free_func, list_add, list_remove, list_destroy) \
401  DYNSTUFF_LIST_DECLARE_WC(lista, type, free_func, list_add, list_remove, list_destroy, __DYNSTUFF_NOCOUNT)
402 
403 #define DYNSTUFF_LIST_DECLARE_NF(lista, type, list_add, list_unlink) \
404  DYNSTUFF_LIST_DECLARE_FULL(lista, type, NULL, NULL, list_add, __DYNSTUFF_NOREMOVE, __DYNSTUFF_NOREMOVE, list_unlink, __DYNSTUFF_NODESTROY, __DYNSTUFF_NOCOUNT)
405 
406 #define DYNSTUFF_LIST_DECLARE_WC(lista, type, free_func, list_add, list_remove, list_destroy, list_count) \
407  DYNSTUFF_LIST_DECLARE_FULL(lista, type, NULL, free_func, list_add, list_remove, __DYNSTUFF_NOREMOVE, __DYNSTUFF_NOUNLINK, list_destroy, list_count)
408 
409 #define DYNSTUFF_LIST_DECLARE_SORTED(lista, type, compare_func, free_func, list_add, list_remove, list_destroy) \
410  DYNSTUFF_LIST_DECLARE_FULL(lista, type, compare_func, free_func, list_add, list_remove, __DYNSTUFF_NOREMOVE, __DYNSTUFF_NOUNLINK, list_destroy, __DYNSTUFF_NOCOUNT)
411 
412 
413 #define DYNSTUFF_LIST_DECLARE2(lista, type, free_func, list_add, list_remove, list_remove2, list_destroy) \
414  DYNSTUFF_LIST_DECLARE_FULL(lista, type, NULL, free_func, list_add, list_remove, list_remove2, __DYNSTUFF_NOUNLINK, list_destroy, __DYNSTUFF_NOCOUNT)
415 
416 #define DYNSTUFF_LIST_DECLARE2_SORTED(lista, type, compare_func, free_func, list_add, list_remove, list_remove2, list_destroy) \
417  DYNSTUFF_LIST_DECLARE_FULL(lista, type, compare_func, free_func, list_add, list_remove, list_remove2, __DYNSTUFF_NOUNLINK, list_destroy, __DYNSTUFF_NOCOUNT)
418 
419 #define DYNSTUFF_LIST_DECLARE_SORTED_NF(lista, type, compare_func, list_add, list_unlink) \
420  DYNSTUFF_LIST_DECLARE_FULL(lista, type, compare_func, NULL, list_add, __DYNSTUFF_NOREMOVE, __DYNSTUFF_NOREMOVE, list_unlink, __DYNSTUFF_NODESTROY, __DYNSTUFF_NOCOUNT)
421 
422 #ifdef __cplusplus
423 }
424 #endif
425 
426 #endif