| |
| /* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ |
| |
| /* FLASK */ |
| |
| /* |
| * Implementation of the double-ended queue type. |
| */ |
| |
| #include <stdlib.h> |
| #include "queue.h" |
| |
| queue_t queue_create(void) |
| { |
| queue_t q; |
| |
| q = (queue_t) malloc(sizeof(struct queue_info)); |
| if (q == NULL) |
| return NULL; |
| |
| q->head = q->tail = NULL; |
| |
| return q; |
| } |
| |
| int queue_insert(queue_t q, queue_element_t e) |
| { |
| queue_node_ptr_t newnode; |
| |
| if (!q) |
| return -1; |
| |
| newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node)); |
| if (newnode == NULL) |
| return -1; |
| |
| newnode->element = e; |
| newnode->next = NULL; |
| |
| if (q->head == NULL) { |
| q->head = q->tail = newnode; |
| } else { |
| q->tail->next = newnode; |
| q->tail = newnode; |
| } |
| |
| return 0; |
| } |
| |
| int queue_push(queue_t q, queue_element_t e) |
| { |
| queue_node_ptr_t newnode; |
| |
| if (!q) |
| return -1; |
| |
| newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node)); |
| if (newnode == NULL) |
| return -1; |
| |
| newnode->element = e; |
| newnode->next = NULL; |
| |
| if (q->head == NULL) { |
| q->head = q->tail = newnode; |
| } else { |
| newnode->next = q->head; |
| q->head = newnode; |
| } |
| |
| return 0; |
| } |
| |
| queue_element_t queue_remove(queue_t q) |
| { |
| queue_node_ptr_t node; |
| queue_element_t e; |
| |
| if (!q) |
| return NULL; |
| |
| if (q->head == NULL) |
| return NULL; |
| |
| node = q->head; |
| q->head = q->head->next; |
| if (q->head == NULL) |
| q->tail = NULL; |
| |
| e = node->element; |
| free(node); |
| |
| return e; |
| } |
| |
| queue_element_t queue_head(queue_t q) |
| { |
| if (!q) |
| return NULL; |
| |
| if (q->head == NULL) |
| return NULL; |
| |
| return q->head->element; |
| } |
| |
| void queue_destroy(queue_t q) |
| { |
| queue_node_ptr_t p, temp; |
| |
| if (!q) |
| return; |
| |
| p = q->head; |
| while (p != NULL) { |
| temp = p; |
| p = p->next; |
| free(temp); |
| } |
| |
| free(q); |
| } |
| |
| int queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp) |
| { |
| queue_node_ptr_t p; |
| int ret; |
| |
| if (!q) |
| return 0; |
| |
| p = q->head; |
| while (p != NULL) { |
| ret = f(p->element, vp); |
| if (ret) |
| return ret; |
| p = p->next; |
| } |
| return 0; |
| } |
| |
| void queue_map_remove_on_error(queue_t q, |
| int (*f) (queue_element_t, void *), |
| void (*g) (queue_element_t, void *), void *vp) |
| { |
| queue_node_ptr_t p, last, temp; |
| int ret; |
| |
| if (!q) |
| return; |
| |
| last = NULL; |
| p = q->head; |
| while (p != NULL) { |
| ret = f(p->element, vp); |
| if (ret) { |
| if (last) { |
| last->next = p->next; |
| if (last->next == NULL) |
| q->tail = last; |
| } else { |
| q->head = p->next; |
| if (q->head == NULL) |
| q->tail = NULL; |
| } |
| |
| temp = p; |
| p = p->next; |
| g(temp->element, vp); |
| free(temp); |
| } else { |
| last = p; |
| p = p->next; |
| } |
| } |
| |
| return; |
| } |
| |
| /* FLASK */ |