blob: 4799db1c1c7306bd67e2e3eb4b4811a3dc70e555 [file] [log] [blame]
Rob Landley15bdc112006-11-01 22:28:46 -05001/* vi: set sw=4 ts=4 :
2 * llist.c - Linked list functions
3 *
4 * Linked list structures have a next pointer as their first element.
5 */
6
7#include "toys.h"
8
Rob Landley9e2b6db2012-07-15 17:22:04 -05009// Call a function (such as free()) on each element of a linked list.
10void llist_traverse(void *list, void (*using)(void *data))
Rob Landley15bdc112006-11-01 22:28:46 -050011{
12 while (list) {
Rob Landley0a04b3e2006-11-03 00:05:52 -050013 void *pop = llist_pop(&list);
Rob Landley9e2b6db2012-07-15 17:22:04 -050014 using(pop);
Rob Landleybdf037f2008-10-23 16:44:30 -050015
16 // End doubly linked list too.
17 if (list==pop) break;
Rob Landley15bdc112006-11-01 22:28:46 -050018 }
19}
Rob Landley0a04b3e2006-11-03 00:05:52 -050020
21// Return the first item from the list, advancing the list (which must be called
22// as &list)
23void *llist_pop(void *list)
24{
25 // I'd use a void ** for the argument, and even accept the typecast in all
26 // callers as documentation you need the &, except the stupid compiler
27 // would then scream about type-punned pointers. Screw it.
28 void **llist = (void **)list;
29 void **next = (void **)*llist;
30 *llist = *next;
31
32 return (void *)next;
33}
Rob Landley6ef04ef2008-01-20 17:34:53 -060034
Rob Landley2c482472012-03-12 00:25:40 -050035void dlist_add_nomalloc(struct double_list **list, struct double_list *new)
36{
37 if (*list) {
38 new->next = *list;
39 new->prev = (*list)->prev;
40 (*list)->prev->next = new;
41 (*list)->prev = new;
42 } else *list = new->next = new->prev = new;
43}
44
45
Rob Landley53c75042010-01-05 10:43:36 -060046// Add an entry to the end of a doubly linked list
Rob Landleybdf037f2008-10-23 16:44:30 -050047struct double_list *dlist_add(struct double_list **list, char *data)
Rob Landley6ef04ef2008-01-20 17:34:53 -060048{
Rob Landley2c482472012-03-12 00:25:40 -050049 struct double_list *new = xmalloc(sizeof(struct double_list));
Rob Landley6ef04ef2008-01-20 17:34:53 -060050
Rob Landley2c482472012-03-12 00:25:40 -050051 new->data = data;
52 dlist_add_nomalloc(list, new);
Rob Landleybdf037f2008-10-23 16:44:30 -050053
Rob Landley2c482472012-03-12 00:25:40 -050054 return new;
Rob Landley6ef04ef2008-01-20 17:34:53 -060055}