1 /***************************************************************************
2  begin       : Sat Jun 28 2003
3  copyright   : (C) 2003-2010 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 /** @file src/base/misc.h
26  *
27  * @short This file contains some macros concerning lists and inheritance.
28  *
29  * <p>
30  * FIRST: Yes, I DO know, macros are very, very bad.
31  * When writing these macros I spent much time debugging them, because the
32  * compiler is not much of a help here.
33  * The validity of a macro is only checked upon invocation,
34  * so if you never use a macro it will never be checked.
35  * </p>
36  * <p>
37  * However, these macros do work just fine and they make some tasks
38  * much easier to handle.
39  * </p>
40  * <p>
41  * The reason for using macros is the lack of templates in C.
42  * When writing Gwenhywfar I often faced the fact that some functions always
43  * appear with many structs defined. The only difference is the name of those
44  * functions and the type of the arguments.
45  * </p>
46  * <p>
47  * The best example is the handling of lists of structs.
48  * In most listable structs there was a variable called @b next which pointed
49  * to the next object in the list. There were also functions like TYPE_next(),
50  * TYPE_add(), TYPE_del() etc for list handling. Whenever I improved the list
51  * mechanism I had to change ALL code files in order to improve them all.
52  * </p>
53  * <p>
54  * These macros are now used to facilitate improvements in list or inheritance
55  * handling code in C.
56  * </p>
57  * <p>
58  * @b NOTE: Please do not change these macros unless you know exactly what you
59  * are doing!
60  * Bugs in the macros will most probably lead to nearly undebuggable results
61  * in code files using them.<br>
62  * You have been warned ;-)
63  * </p>
64  *
65  */
66 
67 #ifndef GWENHYWFAR_MISC_H
68 #define GWENHYWFAR_MISC_H
69 
70 #include <gwenhywfar/gwenhywfarapi.h>
71 #include <gwenhywfar/types.h>
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <string.h>
75 #include <assert.h>
76 
77 
78 #ifdef __cplusplus
79 extern "C" {
80 #endif
81 
82 #define GWEN_LIST_ADD(typ, sr, head) {\
83   typ *curr;                \
84                             \
85   assert(sr);               \
86                             \
87   curr=*head;               \
88   if (!curr) {              \
89     *head=sr;               \
90   }                         \
91   else {                    \
92     while(curr->next) {     \
93       curr=curr->next;      \
94     }                       \
95     curr->next=sr;          \
96   }\
97   }
98 
99 
100 #define GWEN_LIST_INSERT(typ, sr, head) {\
101   typ *curr;                \
102                             \
103   assert(sr);               \
104                             \
105   curr=*head;               \
106   if (!curr) {              \
107     *head=sr;               \
108   }                         \
109   else {                    \
110     sr->next=curr;\
111     *head=sr;\
112   }\
113   }
114 
115 
116 #define GWEN_LIST_DEL(typ, sr, head) {\
117   typ *curr;                   \
118                                \
119   assert(sr);                  \
120   curr=*head;                  \
121   if (curr) {                  \
122     if (curr==sr) {            \
123       *head=curr->next;        \
124     }                          \
125     else {                     \
126       while(curr->next!=sr) {  \
127   curr=curr->next;       \
128       }                        \
129       if (curr)                \
130   curr->next=sr->next;   \
131     }                          \
132   }                            \
133   sr->next=0;\
134   }
135 
136 
137 
138 /*@}*/ /* defgroup */
139 
140 #ifdef __cplusplus
141 }
142 #endif
143 
144 
145 #include <gwenhywfar/memory.h>
146 #include <gwenhywfar/list1.h>
147 
148 
149 
150 
151 #endif
152 
153 
154 
155