vlock-2.2 beta1
[vlock.git] / src / list.c
blob1151668a61401c9d162b2ddf711f97a564cad59f
1 /* list.c -- doubly linked list routines for vlock,
2 * the VT locking program for linux
4 * This program is copyright (C) 2007 Frank Benkstein, and is free
5 * software which is freely distributable under the terms of the
6 * GNU General Public License version 2, included as the file COPYING in this
7 * distribution. It is NOT public domain software, and any
8 * redistribution not permitted by the GNU General Public License is
9 * expressly forbidden without prior written permission from
10 * the author.
14 #include <stdlib.h>
15 #include <stdio.h>
17 #include "util.h"
19 #include "list.h"
21 /* Create a new, empty list. */
22 struct list *list_new(void)
24 struct list *l = malloc(sizeof *l);
26 if (l == NULL)
27 return NULL;
29 l->first = NULL;
30 l->last = NULL;
31 return l;
34 /* Create a (shallow) copy of the given list. */
35 struct list *list_copy(struct list *l)
37 struct list *new_list = list_new();
39 if (new_list == NULL)
40 return NULL;
42 list_for_each(l, item)
43 if (!list_append(new_list, item->data)) {
44 list_free(new_list);
45 return NULL;
48 return new_list;
51 /* Deallocate the given list and all items. */
52 void list_free(struct list *l)
54 list_for_each_manual(l, item) {
55 struct list_item *tmp = item->next;
56 free(item);
57 item = tmp;
60 free(l);
63 /* Calculate the number of items in the given list. */
64 size_t list_length(struct list *l)
66 size_t length = 0;
68 list_for_each(l, item)
69 length++;
71 return length;
74 /* Create a new list item with the given data and add it to the end of the
75 * list. */
76 bool list_append(struct list *l, void *data)
78 struct list_item *item = malloc(sizeof *item);
80 if (item == NULL)
81 return false;
83 item->data = data;
84 item->previous = l->last;
85 item->next = NULL;
87 if (l->last != NULL)
88 l->last->next = item;
90 l->last = item;
92 if (l->first == NULL)
93 l->first = item;
95 return true;
98 /* Remove the given item from the list. Returns the item following the deleted
99 * one or NULL if the given item was the last. */
100 struct list_item *list_delete_item(struct list *l, struct list_item *item)
102 struct list_item *next = item->next;
104 if (item->previous != NULL)
105 item->previous->next = item->next;
107 if (item->next != NULL)
108 item->next->previous = item->previous;
110 if (l->first == item)
111 l->first = item->next;
113 if (l->last == item)
114 l->last = item->previous;
116 free(item);
118 return next;
121 /* Remove the first item with the given data. Does nothing if no item has this
122 * data. */
123 void list_delete(struct list *l, void *data)
125 struct list_item *item = list_find(l, data);
127 if (item != NULL)
128 (void) list_delete_item(l, item);
131 /* Find the first item with the given data. Returns NULL if no item has this
132 * data. */
133 struct list_item *list_find(struct list *l, void *data)
135 list_for_each(l, item)
136 if (item->data == data)
137 return item;
139 return NULL;