summaryrefslogtreecommitdiffstats
path: root/elist.c
diff options
context:
space:
mode:
authorHans Ulrich Niedermann <hun@n-dimensional.de>2007-12-14 16:08:25 +0100
committerHans Ulrich Niedermann <hun@n-dimensional.de>2007-12-14 16:08:25 +0100
commit6749719af90afe9544db14bdd8e2742926f1439c (patch)
tree9bb8edef05f9625be2ccd9bce5cb245af63effc4 /elist.c
downloade2tools-6749719af90afe9544db14bdd8e2742926f1439c.tar.gz
e2tools-6749719af90afe9544db14bdd8e2742926f1439c.tar.xz
e2tools-6749719af90afe9544db14bdd8e2742926f1439c.zip
Upstream's 0.0.16v0.0.16upstream
Diffstat (limited to 'elist.c')
-rw-r--r--elist.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/elist.c b/elist.c
new file mode 100644
index 0000000..e83ef7d
--- /dev/null
+++ b/elist.c
@@ -0,0 +1,198 @@
+/* $Header: /home/ksheff/src/e2tools/RCS/elist.c,v 0.6 2004/04/06 19:34:44 ksheff Exp $ */
+/*
+ * elist.c
+ *
+ * Copyright (C) 2002 Keith W Sheffield. This file may be redistributed
+ * under the terms of the GNU Public License.
+ *
+ */
+
+#ifndef ELIST_C
+#define ELIST_C
+#endif
+
+/* Description */
+/*
+ *
+ *
+ */
+/*
+ * $Log: elist.c,v $
+ * Revision 0.6 2004/04/06 19:34:44 ksheff
+ * Corrected elist_delete to update the previous node if it exists.
+ *
+ * Revision 0.5 2002/06/05 22:05:01 ksheff
+ * Added elist_delete.
+ *
+ * Revision 0.4 2002/06/03 23:02:01 ksheff
+ * Added the function elist_sort().
+ *
+ * Revision 0.3 2002/04/23 01:49:48 ksheff
+ * Added a define for NULL if it doesn't exist.
+ *
+ * Revision 0.2 2002/03/07 07:33:28 ksheff
+ * silenced compiler warnings for calloc return value.
+ *
+ * Revision 0.1 2002/03/07 07:24:35 ksheff
+ * initial revision
+ *
+ */
+
+/* Feature Test Switches */
+/* Headers */
+#include <memory.h>
+#include "elist.h"
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+elist_t *
+elist_new()
+{
+ elist_t *list;
+
+ list = (elist_t *) calloc(sizeof(elist_t), 1);
+ return list;
+}
+
+elist_t *
+elist_delete(elist_t *l, void (*data_free)(void *))
+{
+ elist_t *n;
+
+ if (l)
+ {
+ n = l->next;
+ if (n)
+ n->prev = l->prev;
+ if (l->prev)
+ l->prev->next = n;
+ if (data_free && l->data)
+ (*data_free)(l->data);
+ free(l);
+ l = n;
+ }
+ return(l);
+}
+
+void
+elist_free(elist_t *l, void (*data_free)(void *))
+{
+ elist_t *n;
+
+ if (l)
+ {
+ do
+ {
+ l = elist_delete(l, data_free);
+ } while (l);
+ }
+}
+
+elist_t *
+elist_append(elist_t *l, void *data)
+{
+ elist_t *n;
+ elist_t *t;
+
+ if (NULL == (n = elist_new()))
+ return(NULL);
+
+ n->data = data;
+
+ if (l)
+ {
+ t = l;
+ while (t->next != NULL) t = t->next;
+ t->next = n;
+ n->prev = t;
+ }
+ else
+ l = n;
+
+ return(l);
+}
+
+elist_t *
+elist_insert(elist_t *l, void *data)
+{
+ elist_t *n;
+
+ if (NULL == (n = elist_new()))
+ return(NULL);
+ n->data = data;
+
+ if (l)
+ {
+ n->prev = l->prev;
+ l->prev = n;
+ n->next = l;
+ if (n->prev)
+ n->prev->next = n;
+ }
+ l = n;
+
+ return(l);
+}
+
+void elist_sort(elist_t *l, int (sort_func)(void *, void *), int reverse)
+{
+ int c=0;
+ elist_t *tl;
+ void **data;
+ void **dptr;
+
+ if (l != NULL && sort_func != NULL)
+ {
+ /* count the number of nodes */
+ tl = l;
+ while (tl != NULL)
+ {
+ c++;
+ tl = tl->next;
+ }
+
+ /* if there are more than 1 nodes, allocate a lookup table */
+ if (c > 1 && (NULL != (data = (void **) malloc(c*sizeof(void*)))))
+ {
+ /* fill in the lookup table */
+ tl = l;
+ dptr = data;
+ while (tl != NULL)
+ {
+ *dptr++ = tl->data;
+ tl = tl->next;
+ }
+
+ qsort(data, c, sizeof(dptr), sort_func);
+
+ /* now fill in the data pointers in the linked list with the
+ * data nodes in the correct order
+ */
+ tl = l;
+ if (reverse)
+ {
+ dptr = data + c - 1;
+ while (tl != NULL)
+ {
+ tl->data = *dptr--;
+ tl = tl->next;
+ }
+ }
+ else
+ {
+ dptr = data;
+ while (tl != NULL)
+ {
+ tl->data = *dptr++;
+ tl = tl->next;
+ }
+ }
+ free(data);
+ }
+ }
+}
+
+
+