setools/libqpol/queue.c
Chris PeBenito 8363f8edf7 Import libqpol from setools3.
Break setools3 dependence. Also fix SWIG wrapper to work with SWIG 2.x.
2014-10-24 21:00:24 -04:00

188 lines
2.6 KiB
C

/**
* @file
*
* This file is a copy of queue.c from NSA's CVS repository.
*
* Author : Stephen Smalley, <sds@epoch.ncsc.mil>
*/
/* No changes for SETools libqpol services - Just the header */
/* 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 */