1 2 /* Author : Stephen Smalley, <sds@tycho.nsa.gov> */ 3 4 /* FLASK */ 5 6 /* 7 * Implementation of the double-ended queue type. 8 */ 9 10 #include <stdlib.h> 11 #include "queue.h" 12 13 queue_t queue_create(void) 14 { 15 queue_t q; 16 17 q = (queue_t) malloc(sizeof(struct queue_info)); 18 if (q == NULL) 19 return NULL; 20 21 q->head = q->tail = NULL; 22 23 return q; 24 } 25 26 int queue_insert(queue_t q, queue_element_t e) 27 { 28 queue_node_ptr_t newnode; 29 30 if (!q) 31 return -1; 32 33 newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node)); 34 if (newnode == NULL) 35 return -1; 36 37 newnode->element = e; 38 newnode->next = NULL; 39 40 if (q->head == NULL) { 41 q->head = q->tail = newnode; 42 } else { 43 q->tail->next = newnode; 44 q->tail = newnode; 45 } 46 47 return 0; 48 } 49 50 int queue_push(queue_t q, queue_element_t e) 51 { 52 queue_node_ptr_t newnode; 53 54 if (!q) 55 return -1; 56 57 newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node)); 58 if (newnode == NULL) 59 return -1; 60 61 newnode->element = e; 62 newnode->next = NULL; 63 64 if (q->head == NULL) { 65 q->head = q->tail = newnode; 66 } else { 67 newnode->next = q->head; 68 q->head = newnode; 69 } 70 71 return 0; 72 } 73 74 queue_element_t queue_remove(queue_t q) 75 { 76 queue_node_ptr_t node; 77 queue_element_t e; 78 79 if (!q) 80 return NULL; 81 82 if (q->head == NULL) 83 return NULL; 84 85 node = q->head; 86 q->head = q->head->next; 87 if (q->head == NULL) 88 q->tail = NULL; 89 90 e = node->element; 91 free(node); 92 93 return e; 94 } 95 96 queue_element_t queue_head(queue_t q) 97 { 98 if (!q) 99 return NULL; 100 101 if (q->head == NULL) 102 return NULL; 103 104 return q->head->element; 105 } 106 107 void queue_destroy(queue_t q) 108 { 109 queue_node_ptr_t p, temp; 110 111 if (!q) 112 return; 113 114 p = q->head; 115 while (p != NULL) { 116 free(p->element); 117 temp = p; 118 p = p->next; 119 free(temp); 120 } 121 122 free(q); 123 } 124 125 int queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp) 126 { 127 queue_node_ptr_t p; 128 int ret; 129 130 if (!q) 131 return 0; 132 133 p = q->head; 134 while (p != NULL) { 135 ret = f(p->element, vp); 136 if (ret) 137 return ret; 138 p = p->next; 139 } 140 return 0; 141 } 142 143 void queue_map_remove_on_error(queue_t q, 144 int (*f) (queue_element_t, void *), 145 void (*g) (queue_element_t, void *), void *vp) 146 { 147 queue_node_ptr_t p, last, temp; 148 int ret; 149 150 if (!q) 151 return; 152 153 last = NULL; 154 p = q->head; 155 while (p != NULL) { 156 ret = f(p->element, vp); 157 if (ret) { 158 if (last) { 159 last->next = p->next; 160 if (last->next == NULL) 161 q->tail = last; 162 } else { 163 q->head = p->next; 164 if (q->head == NULL) 165 q->tail = NULL; 166 } 167 168 temp = p; 169 p = p->next; 170 g(temp->element, vp); 171 free(temp); 172 } else { 173 last = p; 174 p = p->next; 175 } 176 } 177 178 return; 179 } 180 181 /* FLASK */ 182