diff options
author | Jouni Malinen <j@w1.fi> | 2009-12-19 13:43:25 +0200 |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2009-12-19 13:43:25 +0200 |
commit | dacf47835208a24ae5ba51c4a869b36339f78897 (patch) | |
tree | c5d38334b051d530cb34d4df949d9d261a1150a8 | |
parent | d2e6100c1671a96377e44efa92d51a75f1d650fa (diff) | |
download | external_wpa_supplicant_8_ti-dacf47835208a24ae5ba51c4a869b36339f78897.zip external_wpa_supplicant_8_ti-dacf47835208a24ae5ba51c4a869b36339f78897.tar.gz external_wpa_supplicant_8_ti-dacf47835208a24ae5ba51c4a869b36339f78897.tar.bz2 |
Add generic doubly-linked list implementation
-rw-r--r-- | src/utils/list.h | 89 | ||||
-rw-r--r-- | tests/.gitignore | 1 | ||||
-rw-r--r-- | tests/Makefile | 6 | ||||
-rw-r--r-- | tests/test-list.c | 78 |
4 files changed, 173 insertions, 1 deletions
diff --git a/src/utils/list.h b/src/utils/list.h new file mode 100644 index 0000000..ed7c022 --- /dev/null +++ b/src/utils/list.h @@ -0,0 +1,89 @@ +/* + * Doubly-linked list + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef LIST_H +#define LIST_H + +/** + * struct dl_list - Doubly-linked list + */ +struct dl_list { + struct dl_list *next; + struct dl_list *prev; +}; + +static inline void dl_list_init(struct dl_list *list) +{ + list->next = list; + list->prev = list; +} + +static inline void dl_list_add(struct dl_list *list, struct dl_list *item) +{ + item->next = list->next; + item->prev = list; + list->next->prev = item; + list->next = item; +} + +static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item) +{ + dl_list_add(list->prev, item); +} + +static inline void dl_list_del(struct dl_list *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; + item->next = NULL; + item->prev = NULL; +} + +static inline int dl_list_empty(struct dl_list *list) +{ + return list->next == list; +} + +static inline unsigned int dl_list_len(struct dl_list *list) +{ + struct dl_list *item; + int count = 0; + for (item = list->next; item != list; item = item->next) + count++; + return count; +} + +#ifndef offsetof +#define offsetof(type, member) ((long) &((type *) 0)->member) +#endif + +#define dl_list_entry(item, type, member) \ + ((type *) ((char *) item - offsetof(type, member))) + +#define dl_list_first(list, type, member) \ + (dl_list_empty((list)) ? NULL : \ + dl_list_entry((list)->next, type, member)) + +#define dl_list_for_each(item, list, type, member) \ + for (item = dl_list_entry((list)->next, type, member); \ + &item->member != (list); \ + item = dl_list_entry(item->member.next, type, member)) + +#define dl_list_for_each_safe(item, n, list, type, member) \ + for (item = dl_list_entry((list)->next, type, member), \ + n = dl_list_entry(item->member.next, type, member); \ + &item->member != (list); \ + item = n, n = dl_list_entry(n->member.next, type, member)) + +#endif /* LIST_H */ diff --git a/tests/.gitignore b/tests/.gitignore index 9c64aa6..5b992a3 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,6 +1,7 @@ test-aes test-asn1 test-base64 +test-list test-md4 test-md5 test-milenage diff --git a/tests/Makefile b/tests/Makefile index dcb9a2d..210a1b4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,5 @@ TESTS=test-base64 test-md4 test-md5 test-milenage test-ms_funcs test-sha1 \ - test-sha256 test-aes test-asn1 test-x509 test-x509v3 + test-sha256 test-aes test-asn1 test-x509 test-x509v3 test-list all: $(TESTS) @@ -45,6 +45,9 @@ test-asn1: test-asn1.o $(LIBS) test-base64: test-base64.o $(LIBS) $(LDO) $(LDFLAGS) -o $@ $^ +test-list: test-list.o $(LIBS) + $(LDO) $(LDFLAGS) -o $@ $^ + test-md4: test-md4.o $(LIBS) $(LDO) $(LDFLAGS) -o $@ $^ @@ -72,6 +75,7 @@ test-x509v3: test-x509v3.o $(LIBS) run-tests: $(TESTS) ./test-aes + ./test-list ./test-md4 ./test-md5 ./test-milenage diff --git a/tests/test-list.c b/tests/test-list.c new file mode 100644 index 0000000..930ce41 --- /dev/null +++ b/tests/test-list.c @@ -0,0 +1,78 @@ +/* + * Doubly-linked list - test program + * Copyright (c) 2009, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "utils/includes.h" +#include "utils/os.h" +#include "utils/list.h" + +struct test { + struct dl_list list; + int value; +}; + +static void dump_list(struct dl_list *head) +{ + struct test *t; + printf("dump:"); + dl_list_for_each(t, head, struct test, list) + printf(" %d", t->value); + printf(" (len=%d%s)\n", dl_list_len(head), + dl_list_empty(head) ? " empty" : ""); +} + +int main(int argc, char *argv[]) +{ + struct dl_list head; + struct test *t, *tmp; + int i; + + dl_list_init(&head); + dump_list(&head); + + for (i = 0; i < 5; i++) { + t = os_zalloc(sizeof(*t)); + if (t == NULL) + return -1; + t->value = i; + dl_list_add(&head, &t->list); + dump_list(&head); + } + + for (i = 10; i > 5; i--) { + t = os_zalloc(sizeof(*t)); + if (t == NULL) + return -1; + t->value = i; + dl_list_add_tail(&head, &t->list); + dump_list(&head); + } + + i = 0; + dl_list_for_each(t, &head, struct test, list) + if (++i == 5) + break; + printf("move: %d\n", t->value); + dl_list_del(&t->list); + dl_list_add(&head, &t->list); + dump_list(&head); + + dl_list_for_each_safe(t, tmp, &head, struct test, list) { + printf("delete: %d\n", t->value); + dl_list_del(&t->list); + os_free(t); + dump_list(&head); + } + + return 0; +} |