
/* Author : Stephen Smalley, <sds@tycho.nsa.gov> */

/* 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) {
		free(p->element);
		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 */
