--- /dev/null
+/* Evil linked-list implementation in C with macros
+
+ Copyright (C) 1999 Evin Robertson
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+
+ The author can be reached at ecr+@andrew.cmu.edu
+*/
+
+
+#define LEaddm(list, member, mallocfunc) do { \
+ void *temppointer = list; \
+ list = mallocfunc(sizeof(*list)); \
+ *list = member; \
+ list->next = temppointer; \
+ } while(0)
+
+#define LEadd(list, member) LEaddm(list, member, n_malloc)
+
+#define LEremovem(list, freefunc) do { \
+ if(list) { \
+ void *temppointer = list; \
+ list = list->next; \
+ freefunc(temppointer); \
+ } \
+ } while(0);
+
+#define LEremove(list) LEremovem(list, n_free)
+
+
+#define LEdestructm(list, destruct, freefunc) do { \
+ while(list) { \
+ void *temppointer = list; \
+ destruct; \
+ list = list->next; \
+ freefunc(temppointer); \
+ } \
+ } while(0)
+
+#define LEdestruct(list, destruct) LEdestructm(list, destruct, n_free)
+
+#define LEdestroym(list, freefunc) LEdestructm(list, , freefunc)
+
+#define LEdestroy(list) LEdestroym(list, n_free)
+
+
+#define LEsearch(list, dest, cond) \
+ do { \
+ for(dest = list; dest; dest=dest->next) \
+ if(cond) break; \
+ } while(0)
+
+/* temp != NULL if it successfully performed the removal */
+#define LEsearchremovem(list, dest, temp, cond, destruct, freefunc) \
+ do { \
+ dest = list; \
+ if(dest && (cond)) { \
+ temp = dest; \
+ destruct; \
+ LEremovem(list, freefunc); \
+ } else { \
+ for(temp = list; temp; temp=temp->next) { \
+ dest=temp->next; \
+ if(dest && (cond)) { \
+ temp->next = dest->next; \
+ destruct; \
+ freefunc(dest); \
+ } \
+ } \
+ } \
+ } while(0)
+
+#define LEsearchremove(list, dest, temp, cond, destruct) LEsearchremovem(list, dest, temp, cond, destruct, n_free)
+
+#define LEappend(dest, src) do { \
+ void *temppointer = dest; \
+ if(dest) { \
+ while(dest->next) \
+ dest = dest->next; \
+ dest->next = src; \
+ dest = temppointer; \
+ } else { \
+ dest = scr; \
+ } \
+ } while(0)
+
+
+
+
+/* This is just an example: */
+#if 0
+
+/*
+Use: Declare a struct like this:
+*/
+typedef struct {
+ struct mylist *next; /* The evil linked list library depends on this */
+ int myint;
+ char *mystring;
+} mylist;
+
+
+void foo() {
+ mylist *foo = NULL;
+ mylist *found;
+ mylist *another = NULL;
+
+ mylist mymember1 = { NULL, 42, "frogs" };
+ mylist mymember2 = { NULL, 38, "potato" };
+ mylist mymember3 = { NULL, 21, "monkey" };
+
+ LEremove(foo); /* Remove nonexistent head element - this is safe */
+
+ LEadd(foo, mymember1); /* Add an element to the head */
+ LEadd(foo, mymember2); /* Add another element to the head */
+ LEadd(foo, mymember3);
+ LEadd(foo, mymember1);
+
+ LEremove(foo); /* Remove the head element */
+
+ LEsearch(foo, found, (strcmp(found->mystring, "potato") == 0));
+
+ LEdup(another, found);
+
+ LEdestroy(foo);
+
+ LEadd(foo, mymember3);
+
+ LEprepend(another, foo);
+}
+
+#endif