1 /* NFSv4.1 client for Windows 2 * Copyright � 2012 The Regents of the University of Michigan 3 * 4 * Olga Kornievskaia <aglo@umich.edu> 5 * Casey Bodley <cbodley@umich.edu> 6 * 7 * This library is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation; either version 2.1 of the License, or (at 10 * your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, but 13 * without any warranty; without even the implied warranty of merchantability 14 * or fitness for a particular purpose. See the GNU Lesser General Public 15 * License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 */ 21 22 #ifndef NFS41_LIST_H 23 #define NFS41_LIST_H 24 25 26 /* doubly-linked list */ 27 struct list_entry { 28 struct list_entry *prev; 29 struct list_entry *next; 30 }; 31 32 33 #define list_container(entry, type, field) \ 34 ((type*)((const char*)(entry) - (const char*)(&((type*)0)->field))) 35 36 #define list_for_each(entry, head) \ 37 for (entry = (head)->next; entry != (head); entry = entry->next) 38 39 #define list_for_each_tmp(entry, tmp, head) \ 40 for (entry = (head)->next, tmp = entry->next; entry != (head); \ 41 entry = tmp, tmp = entry->next) 42 43 #define list_for_each_reverse(entry, head) \ 44 for (entry = (head)->prev; entry != (head); entry = entry->prev) 45 46 #define list_for_each_reverse_tmp(entry, tmp, head) \ 47 for (entry = (head)->next, tmp = entry->next; entry != (head); \ 48 entry = tmp, tmp = entry->next) 49 50 51 static void list_init( 52 struct list_entry *head) 53 { 54 head->prev = head; 55 head->next = head; 56 } 57 58 static int list_empty( 59 struct list_entry *head) 60 { 61 return head->next == head; 62 } 63 64 static void list_add( 65 struct list_entry *entry, 66 struct list_entry *prev, 67 struct list_entry *next) 68 { 69 /* assert(prev->next == next && next->prev == prev); */ 70 entry->prev = prev; 71 entry->next = next; 72 prev->next = entry; 73 next->prev = entry; 74 } 75 76 static void list_add_head( 77 struct list_entry *head, 78 struct list_entry *entry) 79 { 80 list_add(entry, head, head->next); 81 } 82 83 static void list_add_tail( 84 struct list_entry *head, 85 struct list_entry *entry) 86 { 87 list_add(entry, head->prev, head); 88 } 89 90 static void list_remove( 91 struct list_entry *entry) 92 { 93 if (!list_empty(entry)) { 94 entry->next->prev = entry->prev; 95 entry->prev->next = entry->next; 96 list_init(entry); 97 } 98 } 99 100 typedef int (*list_compare_fn)(const struct list_entry*, const void*); 101 102 static struct list_entry* list_search( 103 const struct list_entry *head, 104 const void *value, 105 list_compare_fn compare) 106 { 107 struct list_entry *entry; 108 list_for_each(entry, head) 109 if (compare(entry, value) == 0) 110 return entry; 111 return NULL; 112 } 113 114 #endif /* !NFS41_LIST_H */ 115