Added Nitfol and Frotz source code.
[projects/chimara/chimara.git] / interpreters / nitfol / linkevil.h
diff --git a/interpreters/nitfol/linkevil.h b/interpreters/nitfol/linkevil.h
new file mode 100644 (file)
index 0000000..df65116
--- /dev/null
@@ -0,0 +1,144 @@
+/*  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