df65116218995d53e74ac05599aaefd1db47abaf
[projects/chimara/chimara.git] / interpreters / nitfol / linkevil.h
1 /*  Evil linked-list implementation in C with macros
2
3     Copyright (C) 1999  Evin Robertson
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
18
19     The author can be reached at ecr+@andrew.cmu.edu
20 */
21
22
23 #define LEaddm(list, member, mallocfunc) do {                              \
24                               void *temppointer = list;       \
25                               list = mallocfunc(sizeof(*list)); \
26                               *list = member;                 \
27                               list->next = temppointer;       \
28                             } while(0)
29
30 #define LEadd(list, member) LEaddm(list, member, n_malloc)
31
32 #define LEremovem(list, freefunc)  do {                       \
33                               if(list) {                      \
34                                 void *temppointer = list;     \
35                                 list = list->next;            \
36                                 freefunc(temppointer);        \
37                               }                               \
38                             } while(0);
39
40 #define LEremove(list) LEremovem(list, n_free)
41
42
43 #define LEdestructm(list, destruct, freefunc) do {            \
44                               while(list) {                   \
45                                 void *temppointer = list;     \
46                                 destruct;                     \
47                                 list = list->next;            \
48                                 freefunc(temppointer);        \
49                               }                               \
50                             } while(0)
51
52 #define LEdestruct(list, destruct) LEdestructm(list, destruct, n_free)
53      
54 #define LEdestroym(list, freefunc) LEdestructm(list, , freefunc)
55
56 #define LEdestroy(list) LEdestroym(list, n_free)
57
58
59 #define LEsearch(list, dest, cond)                            \
60                             do {                              \
61                               for(dest = list; dest; dest=dest->next)  \
62                                 if(cond) break;               \
63                             } while(0)
64
65 /* temp != NULL if it successfully performed the removal */
66 #define LEsearchremovem(list, dest, temp, cond, destruct, freefunc) \
67                             do {                              \
68                               dest = list;                    \
69                               if(dest && (cond)) {            \
70                                 temp = dest;                  \
71                                 destruct;                     \
72                                 LEremovem(list, freefunc);    \
73                               } else {                        \
74                                 for(temp = list; temp; temp=temp->next) { \
75                                   dest=temp->next;            \
76                                   if(dest && (cond)) {        \
77                                     temp->next = dest->next;  \
78                                     destruct;                 \
79                                     freefunc(dest);           \
80                                   }                           \
81                                 }                             \
82                               }                               \
83                             } while(0)
84
85 #define LEsearchremove(list, dest, temp, cond, destruct) LEsearchremovem(list, dest, temp, cond, destruct, n_free)
86
87 #define LEappend(dest, src) do {                              \
88                               void *temppointer = dest;       \
89                               if(dest) {                      \
90                                 while(dest->next)             \
91                                   dest = dest->next;          \
92                                 dest->next = src;             \
93                                 dest = temppointer;           \
94                               } else {                        \
95                                 dest = scr;                   \
96                               }                               \
97                             } while(0)
98
99
100
101
102 /* This is just an example: */
103 #if 0
104
105 /*
106 Use: Declare a struct like this:
107 */
108 typedef struct {
109   struct mylist *next;     /* The evil linked list library depends on this */
110   int myint;
111   char *mystring;
112 } mylist;
113
114
115 void foo() {
116   mylist *foo = NULL;
117   mylist *found;
118   mylist *another = NULL;
119
120   mylist mymember1 = { NULL, 42, "frogs" };
121   mylist mymember2 = { NULL, 38, "potato" };
122   mylist mymember3 = { NULL, 21, "monkey" };
123
124   LEremove(foo);           /* Remove nonexistent head element - this is safe */
125
126   LEadd(foo, mymember1);   /* Add an element to the head */
127   LEadd(foo, mymember2);   /* Add another element to the head */
128   LEadd(foo, mymember3);
129   LEadd(foo, mymember1);
130
131   LEremove(foo);           /* Remove the head element */
132
133   LEsearch(foo, found, (strcmp(found->mystring, "potato") == 0));
134
135   LEdup(another, found);
136
137   LEdestroy(foo);
138
139   LEadd(foo, mymember3);
140
141   LEprepend(another, foo);
142 }
143
144 #endif