1 /***************************************************************************
2  begin       : Sat Jun 28 2003
3  copyright   : (C) 2018 by Martin Preuss
4  email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *                                                                         *
8  *   This library is free software; you can redistribute it and/or         *
9  *   modify it under the terms of the GNU Lesser General Public            *
10  *   License as published by the Free Software Foundation; either          *
11  *   version 2.1 of the License, or (at your option) any later version.    *
12  *                                                                         *
13  *   This library is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
16  *   Lesser General Public License for more details.                       *
17  *                                                                         *
18  *   You should have received a copy of the GNU Lesser General Public      *
19  *   License along with this library; if not, write to the Free Software   *
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21  *   MA  02111-1307  USA                                                   *
22  *                                                                         *
23  ***************************************************************************/
24 
25 
26 #include <gwenhywfar/gwenhywfarapi.h>
27 #include <gwenhywfar/types.h>
28 #include <assert.h>
29 
30 
31 #ifndef GWEN_DUMMY_EMPTY_ARG
32 /** Necessary for MSVC compiler because it does not accept a left-out
33     macro argument. */
34 # define GWEN_DUMMY_EMPTY_ARG
35 #endif
36 
37 
38 #ifndef GWEN_LIST1_H
39 #define GWEN_LIST1_H
40 
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 
47 /** @defgroup GWEN_MACRO_LIST Macros For Typesafe List Handling
48  *
49  * The macros of this group facilitates typesafe use of lists.
50  *
51  * <p>
52  * Let's assume you have a structure type called MYSTRUCT and you want
53  * to manage lists of them. Let's further assume that you want the
54  * functions dealing with that struct have prefixes like MyStruct (as in
55  * @b MyStruct_new)
56  * </p>
57  * The header file would look like this:
58  *
59  * @code
60  *
61  * / * mystruct.h * /
62  *
63  * #ifndef MYSTRUCT_H
64  * #define MYSTRUCT_H
65  *
66  * typedef struct MYSTRUCT MYSTRUCT;
67  *
68  * GWEN_LIST_FUNCTION_DEFS(MYSTRUCT, MyStruct);
69  *
70  * struct MYSTRUCT {
71  *   GWEN_LIST_ELEMENT(MYSTRUCT);
72  *   int myData;
73  * }
74  *
75  *
76  * MYSTRUCT *MyStruct_new(int myData);
77  * void MyStruct_free(MYSTRUCT *myStruct);
78  *
79  * #endif
80  * @endcode
81  * <p>
82  * This defines all necessary data and function prototypes needed for
83  * list management.
84  * </p>
85  *
86  * <p>
87  * The code file would look quite similar to the following:
88  * </p>
89  *
90  * @code
91  *
92  * / * mystruct.c * /
93  *
94  * GWEN_LIST_FUNCTIONS(MYSTRUCT, MyStruct)
95  *
96  * MYSTRUCT *MyStruct_new(int myData) {
97  *   MYSTRUCT *pMyStruct;
98  *
99  *   pMyStruct=(MYSTRUCT*)malloc(sizeof(MYSTRUCT));
100  *   memset(pMyStruct, 0, sizeof(MYSTRUCT));
101  *
102  *   GWEN_LIST_INIT(MYSTRUCT, pMyStruct)
103  *
104  *   pMyStruct->myData=myData;
105  *   return pMyStruct;
106  * }
107  *
108  * void MyStruct_free(MYSTRUCT *pMyStruct) {
109  *   if (pMyStruct) {
110  *     pMyStruct->myData=0;
111  *
112  *     GWEN_LIST_FINI(MYSTRUCT, pMyStruct)
113  *
114  *     free(pMyStruct);
115  *   }
116  * }
117  *
118  * @endcode
119  * Please note the three macros used in the code file:
120  * <ul>
121  *   <li>@ref GWEN_LIST_FUNCTIONS creates the functions for the list
122  *       management</li>
123  *   <li>@ref GWEN_LIST_INIT initializes the list data inside your
124  *       struct to defined values </li>
125  *   <li>@ref GWEN_LIST_FINI frees all ressources occupied by the list
126  *       management code. Please note that this macro should be the last
127  *       statement inside the destructor function before @b free()</li>
128  * </ul>
129  *
130  * <p>Note: When writing these macro code lines, the original ISO
131  * C89 standard for the C language does not allow terminating the
132  * macro statement with a semicolon ';'. Any recent compiler will
133  * probably silently ignore such an extra ';', but you should be
134  * aware that this can cause problems once one of your users tries
135  * to compile this with a different compiler. Therefore these code
136  * lines should end directly with the closing parentheses.</p>
137  *
138  * <p>
139  * The list management code assumes that there is a function called
140  * (in this example) @b MyStruct_free() (or generally: TYPEPREFIX_free).
141  * This is used when destroying a list of MYSTRUCT elements. In this case
142  * all elements still enlisted are destroyed upon destruction of the list.
143  * </p>
144  */
145 /*@{*/
146 
147 
148 /** @name Internal Functions
149  *
150  * All functions and structs within this group should be considered
151  * internal. They just implement the functionality behind the typesafe list
152  * macros (see @ref GWEN_LIST_FUNCTION_LIB_DEFS and following).
153  */
154 /*@{*/
155 typedef struct GWEN_LIST1 GWEN_LIST1;
156 typedef struct GWEN_LIST1_ELEMENT GWEN_LIST1_ELEMENT;
157 
158 typedef int GWENHYWFAR_CB(*GWEN_LIST1_SORT_FN)(const void *a, const void *b, int ascending);
159 
160 
161 /** Allocate (create) a new empty list. */
162 GWENHYWFAR_API
163 GWEN_LIST1 *GWEN_List1_new(void);
164 
165 /** Free (delete) an existing list.  The list elements are
166  * untouched by this function; they need to be freed
167  * beforehand. */
168 GWENHYWFAR_API
169 void GWEN_List1_free(GWEN_LIST1 *l);
170 
171 /** Returns the number of elements in this list. This value is
172  * cached in the list structure, so this function is a cheap
173  * function. */
174 GWENHYWFAR_API
175 int GWEN_List1_GetCount(const GWEN_LIST1 *l);
176 
177 /** Adds (appends) a list element at the end of the list. (This
178  * operation is also called "append" or "push_back" elsewhere.) */
179 GWENHYWFAR_API
180 int GWEN_List1_Add(GWEN_LIST1 *l, GWEN_LIST1_ELEMENT *el);
181 
182 /** Inserts (prepends) a list element at the beginning of the
183  * list. (This operation is also called "prepend" or "push_front"
184  * elsewhere.) */
185 GWENHYWFAR_API
186 int GWEN_List1_Insert(GWEN_LIST1 *l, GWEN_LIST1_ELEMENT *el);
187 
188 /** Deletes (removes) a list element from the list it used to
189  * belong to. The list element is not free'd or anything, it is
190  * only removed from the list it used to belong to. (This
191  * operation is also called "remove" or "unlink" elsewhere.) */
192 GWENHYWFAR_API
193 int GWEN_List1_Del(GWEN_LIST1_ELEMENT *el);
194 
195 /** Adds (appends) the second list to the end of the first
196  * list. (This operation is also called "append" or "concatenate"
197  * elsewhere.) */
198 GWENHYWFAR_API
199 int GWEN_List1_AddList(GWEN_LIST1 *dest, GWEN_LIST1 *l);
200 
201 /** Returns the data pointer of the first list element. */
202 GWENHYWFAR_API
203 void *GWEN_List1_GetFirst(const GWEN_LIST1 *l);
204 
205 /** Returns the data pointer of the last list element. */
206 GWENHYWFAR_API
207 void *GWEN_List1_GetLast(const GWEN_LIST1 *l);
208 
209 GWENHYWFAR_API
210 GWEN_LIST1_SORT_FN GWEN_List1_SetSortFn(GWEN_LIST1 *l, GWEN_LIST1_SORT_FN fn);
211 
212 GWENHYWFAR_API
213 void GWEN_List1_Sort(GWEN_LIST1 *l, int ascending);
214 
215 
216 
217 /** Allocate (create) a new list element structure. */
218 GWENHYWFAR_API
219 GWEN_LIST1_ELEMENT *GWEN_List1Element_new(void *d);
220 
221 /** Free (delete) a list element structure. */
222 GWENHYWFAR_API
223 void GWEN_List1Element_free(GWEN_LIST1_ELEMENT *el);
224 
225 /** Returns the data pointer of the given list element
226  * structure. */
227 GWENHYWFAR_API
228 void *GWEN_List1Element_GetData(const GWEN_LIST1_ELEMENT *el);
229 
230 /** Returns the data pointer of the list element that is the
231  * previous (predecessor) to the given one in its list. If there
232  * is no such prepending list element, returns NULL. */
233 GWENHYWFAR_API
234 void *GWEN_List1Element_GetPrevious(const GWEN_LIST1_ELEMENT *el);
235 
236 /** Returns the data pointer of the list element that is the next
237  * one (successor) to the given one in its list. If there is no
238  * such prepending list element, returns NULL. */
239 GWENHYWFAR_API
240 void *GWEN_List1Element_GetNext(const GWEN_LIST1_ELEMENT *el);
241 
242 
243 /*@}*/
244 
245 
246 /** @name Typesafe Macros
247  *
248  */
249 /*@{*/
250 
251 /**
252  * Use this inside the declaration of a struct for which you want to create
253  * lists.
254  */
255 #define GWEN_LIST_ELEMENT(t) \
256 GWEN_LIST1_ELEMENT *_list1_element;
257 
258 /**
259  * Use this macro in your public header files to export only list functions
260  * which do not modify a list. This allows your code to return lists which can
261  * not be modified by callers. It also prevents callers from creating their
262  * own lists (this is sometimes needed).
263  */
264 #define GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, decl) \
265   typedef GWEN_LIST1 t##_LIST; \
266   typedef int GWENHYWFAR_CB (*t##_LIST_SORT_FN)(const t *a, const t *b, int ascending); \
267   typedef t* (t##_LIST_FOREACH)(t *element, void *user_data); \
268                                                                                         \
269   \
270   decl t* pr##_List_First(const t##_LIST *l); \
271   decl t* pr##_List_Last(const t##_LIST *l); \
272   decl t* pr##_List_Next(const t *element); \
273   decl t* pr##_List_Previous(const t *element); \
274   decl uint32_t pr##_List_GetCount(const t##_LIST *l); \
275   decl int pr##_List_HasElement(const t##_LIST *l, const t *element); \
276   decl t##_LIST_SORT_FN pr##_List_SetSortFn(t##_LIST *l, t##_LIST_SORT_FN fn); \
277   decl void pr##_List_Sort(t##_LIST *l, int ascending); \
278   decl t* pr##_List_ForEach(t##_LIST *l, t##_LIST_FOREACH fn, void *user_data);
279 
280 
281 #define GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, decl) \
282   typedef GWEN_LIST1_ELEMENT t##_LIST_ELEMENT; \
283   \
284   decl void pr##_List_Clear(t##_LIST *l); \
285   decl t##_LIST* pr##_List_new(); \
286   decl void pr##_List_free(t##_LIST *l); \
287   decl int pr##_List_AddList(t##_LIST *dst, t##_LIST *l); \
288   decl int pr##_List_Add(t *element, t##_LIST *list); \
289   decl int pr##_List_Insert(t *element, t##_LIST *list); \
290   decl int pr##_List_Del(t *element);
291 
292 
293 #define GWEN_LIST_FUNCTION_DEFS_CONST(t, pr) \
294   GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, GWEN_DUMMY_EMPTY_ARG)
295 
296 #define GWEN_LIST_FUNCTION_DEFS_NOCONST(t, pr) \
297   GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, GWEN_DUMMY_EMPTY_ARG)
298 
299 
300 /**
301  * Use this in public header files to define some prototypes for list
302  * functions.
303  * Let's assume the type of your list elements is "MYTYPE" and you want to
304  * use the prefix "MyType_" for the list functions.
305  * The following function prototypes will then be created:
306  * <ul>
307  *  <li>
308  *    void MyType_List_Add(MYTYPE *element, MYTYPE_LIST *list);<br>
309  *    Adds (appends) a MYTYPE struct at the end of the given
310  *    list. (We apologize for the unusual argument order here.)
311  *  </li>
312  *  <li>
313  *    void MyType_List_Del(MYTYPE *element);<br>
314  *    Removes a MyType struct from the list it is enlisted to.
315  *  </li>
316  *  <li>
317  *    MYTYPE *MyType_List_First(MYTYPE *element); <br>
318  *    Returns the first element of the given list.
319  *  </li>
320  *  <li>
321  *    MYTYPE* MyType_List_Next(const MYTYPE *element);<br>
322  *    Returns the next list element to the given one (the
323  *    successor) in its list.
324  *  </li>
325  *  <li>
326  *    MYTYPE* MyType_List_Previous(const MYTYPE *element);<br>
327  *    Returns the previous list element to the given one (the
328  *    predecessor) in its list.
329  *  </li>
330  *  <li>
331  *    void MyType_List_Clear(MYTYPE *element); <br>
332  *    Frees all entries of the given list.
333  *    This function assumes that there is a function Mytype_free().
334  *  </li>
335  *  <li>
336  *    MYTYPE_LIST *MyType_List_new(); <br>
337  *    Creates a new list of elements of MYTYPE type.
338  *  </li>
339  *  <li>
340  *    void MyType_List_free(MYTYPE_LIST *l); <br>
341  *    Clears and frees a list of elements of MYTYPE type.
342  *    All objects inside the list are freed.
343  *    This function assumes that there is a function Mytype_free().
344  *  </li>
345  * </ul>
346  *
347  */
348 #define GWEN_LIST_FUNCTION_LIB_DEFS(t, pr, decl) \
349   GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, decl) \
350   GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, decl)
351 
352 
353 /**
354  * This macro should be used in applications, not in libraries. In
355  * libraries please use the macro @ref GWEN_LIST_FUNCTION_LIB_DEFS.
356  */
357 #define GWEN_LIST_FUNCTION_DEFS(t, pr) \
358   GWEN_LIST_FUNCTION_LIB_DEFS(t, pr, GWEN_DUMMY_EMPTY_ARG)
359 
360 
361 /**
362  * Use this inside your code files (*.c).
363  * Actually implements the functions for which the prototypes have been
364  * defined via @ref GWEN_LIST_FUNCTION_DEFS.
365  */
366 #define GWEN_LIST_FUNCTIONS(t, pr) \
367   \
368   int pr##_List_Add(t *element, t##_LIST *l) { \
369     return GWEN_List1_Add(l, element->_list1_element); \
370   } \
371   \
372   int pr##_List_AddList(t##_LIST *dst, t##_LIST *l) { \
373     return GWEN_List1_AddList(dst, l); \
374   } \
375   \
376   int pr##_List_Insert(t *element, t##_LIST *l) { \
377     return GWEN_List1_Insert(l, element->_list1_element); \
378   } \
379   \
380   int pr##_List_Del(t *element){ \
381     return GWEN_List1_Del(element->_list1_element); \
382   }\
383   \
384   t* pr##_List_First(const t##_LIST *l) { \
385     if (l) return (t*)GWEN_List1_GetFirst(l);\
386     else return 0; \
387   } \
388   \
389   t* pr##_List_Last(const t##_LIST *l) { \
390     if (l) return (t*) GWEN_List1_GetLast(l);\
391     else return 0; \
392   } \
393   \
394   void pr##_List_Clear(t##_LIST *l) { \
395     t* el; \
396     while( (el=(t*) GWEN_List1_GetFirst(l)) ) {\
397       pr##_List_Del(el);\
398       pr##_free(el);\
399     } /* while */ \
400   } \
401   \
402   int pr##_List_HasElement(const t##_LIST *l, const t *element) { \
403     const t* el; \
404     el=(t*)GWEN_List1_GetFirst(l); \
405     while(el) {\
406       if (el==element) \
407         return 1; \
408       el=(const t*)GWEN_List1Element_GetNext(el->_list1_element); \
409     } /* while */ \
410     return 0; \
411   } \
412   \
413   t##_LIST* pr##_List_new(){\
414     return (t##_LIST*)GWEN_List1_new(); \
415   }\
416   \
417   void pr##_List_free(t##_LIST *l) {\
418     if (l) { \
419       pr##_List_Clear(l);\
420       GWEN_List1_free(l); \
421     }\
422   } \
423   \
424   t* pr##_List_Next(const t *element) { \
425     return (t*)GWEN_List1Element_GetNext(element->_list1_element);\
426   } \
427   \
428   t* pr##_List_Previous(const t *element) { \
429     return (t*)GWEN_List1Element_GetPrevious(element->_list1_element);\
430   } \
431   \
432   uint32_t pr##_List_GetCount(const t##_LIST *l){\
433     return GWEN_List1_GetCount(l);\
434   } \
435   \
436   t##_LIST_SORT_FN pr##_List_SetSortFn(t##_LIST *l, t##_LIST_SORT_FN fn) { \
437     return (t##_LIST_SORT_FN) GWEN_List1_SetSortFn(l, (GWEN_LIST1_SORT_FN) fn); \
438   } \
439   \
440   void pr##_List_Sort(t##_LIST *l, int ascending){\
441     GWEN_List1_Sort(l, ascending);\
442   }\
443   \
444   t* pr##_List_ForEach(t##_LIST *l, t##_LIST_FOREACH fn, void *user_data){ \
445     t *el; \
446     if (!l) return 0; \
447     \
448     el=pr##_List_First(l); \
449     while(el) { \
450       t *elReturned; \
451       elReturned=fn(el, user_data); \
452       if (elReturned) { \
453         return elReturned; \
454       } \
455       el=pr##_List_Next(el); \
456     } \
457     return 0; \
458   }
459 
460 /**
461  * Use this in your code file (*.c) inside the init code for the struct
462  * you want to use in lists (in GWEN these are the functions which end with
463  * "_new".
464  */
465 #define GWEN_LIST_INIT(t, element) \
466   element->_list1_element=GWEN_List1Element_new(element);
467 
468 
469 /**
470  * Use this in your code file (*.c) inside the fini code for the struct
471  * you want to use in lists (in GWEN these are the functions which end with
472  * "_free".
473  */
474 #define GWEN_LIST_FINI(t, element) \
475   if (element && element->_list1_element) { \
476     GWEN_List1Element_free(element->_list1_element); \
477     element->_list1_element=0; \
478   }
479 
480 /*@}*/
481 
482 /*@}*/ /* defgroup */
483 
484 
485 #ifdef __cplusplus
486 }
487 #endif
488 
489 
490 #endif
491 
492 
493