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