diff options
Diffstat (limited to 'libqpol/src/queue.c')
-rw-r--r-- | libqpol/src/queue.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/libqpol/src/queue.c b/libqpol/src/queue.c new file mode 100644 index 0000000..18667d5 --- /dev/null +++ b/libqpol/src/queue.c @@ -0,0 +1,183 @@ +/** + * @file + * + * This file is a copy of queue.c from NSA's CVS repository. + * + * 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 */ |