1 2 /* Author : Stephen Smalley, <sds (at) epoch.ncsc.mil> */ 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 temp = p; 117 p = p->next; 118 free(temp); 119 } 120 121 free(q); 122 } 123 124 int queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp) 125 { 126 queue_node_ptr_t p; 127 int ret; 128 129 if (!q) 130 return 0; 131 132 p = q->head; 133 while (p != NULL) { 134 ret = f(p->element, vp); 135 if (ret) 136 return ret; 137 p = p->next; 138 } 139 return 0; 140 } 141 142 void queue_map_remove_on_error(queue_t q, 143 int (*f) (queue_element_t, void *), 144 void (*g) (queue_element_t, void *), void *vp) 145 { 146 queue_node_ptr_t p, last, temp; 147 int ret; 148 149 if (!q) 150 return; 151 152 last = NULL; 153 p = q->head; 154 while (p != NULL) { 155 ret = f(p->element, vp); 156 if (ret) { 157 if (last) { 158 last->next = p->next; 159 if (last->next == NULL) 160 q->tail = last; 161 } else { 162 q->head = p->next; 163 if (q->head == NULL) 164 q->tail = NULL; 165 } 166 167 temp = p; 168 p = p->next; 169 g(temp->element, vp); 170 free(temp); 171 } else { 172 last = p; 173 p = p->next; 174 } 175 } 176 177 return; 178 } 179 180 /* FLASK */ 181