113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* FLASK */
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Implementation of the double-ended queue type.
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h>
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "queue.h"
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlequeue_t queue_create(void)
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_t q;
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	q = (queue_t) malloc(sizeof(struct queue_info));
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (q == NULL)
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return NULL;
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	q->head = q->tail = NULL;
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return q;
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint queue_insert(queue_t q, queue_element_t e)
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_node_ptr_t newnode;
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!q)
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (newnode == NULL)
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	newnode->element = e;
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	newnode->next = NULL;
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (q->head == NULL) {
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		q->head = q->tail = newnode;
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	} else {
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		q->tail->next = newnode;
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		q->tail = newnode;
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint queue_push(queue_t q, queue_element_t e)
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_node_ptr_t newnode;
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!q)
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (newnode == NULL)
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	newnode->element = e;
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	newnode->next = NULL;
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (q->head == NULL) {
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		q->head = q->tail = newnode;
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	} else {
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		newnode->next = q->head;
6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		q->head = newnode;
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlequeue_element_t queue_remove(queue_t q)
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_node_ptr_t node;
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_element_t e;
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!q)
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return NULL;
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (q->head == NULL)
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return NULL;
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	node = q->head;
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	q->head = q->head->next;
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (q->head == NULL)
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		q->tail = NULL;
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	e = node->element;
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(node);
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return e;
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlequeue_element_t queue_head(queue_t q)
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!q)
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return NULL;
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (q->head == NULL)
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return NULL;
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return q->head->element;
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid queue_destroy(queue_t q)
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_node_ptr_t p, temp;
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!q)
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	p = q->head;
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (p != NULL) {
11647f61b0ee9a8ed85e935941d2dd7a34e4e7a42d2Nicolas Iooss		free(p->element);
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		temp = p;
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		p = p->next;
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		free(temp);
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(q);
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp)
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_node_ptr_t p;
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int ret;
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!q)
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	p = q->head;
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (p != NULL) {
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ret = f(p->element, vp);
13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (ret)
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return ret;
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		p = p->next;
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid queue_map_remove_on_error(queue_t q,
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			       int (*f) (queue_element_t, void *),
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			       void (*g) (queue_element_t, void *), void *vp)
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	queue_node_ptr_t p, last, temp;
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int ret;
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!q)
15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	last = NULL;
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	p = q->head;
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (p != NULL) {
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ret = f(p->element, vp);
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (ret) {
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (last) {
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				last->next = p->next;
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				if (last->next == NULL)
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					q->tail = last;
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			} else {
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				q->head = p->next;
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				if (q->head == NULL)
16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					q->tail = NULL;
16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			temp = p;
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			p = p->next;
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			g(temp->element, vp);
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			free(temp);
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		} else {
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			last = p;
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			p = p->next;
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return;
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* FLASK */
182