16cd6a6acSopenharmony_ci
26cd6a6acSopenharmony_ci/* Author : Stephen Smalley, <sds@tycho.nsa.gov> */
36cd6a6acSopenharmony_ci
46cd6a6acSopenharmony_ci/* FLASK */
56cd6a6acSopenharmony_ci
66cd6a6acSopenharmony_ci/*
76cd6a6acSopenharmony_ci * Implementation of the double-ended queue type.
86cd6a6acSopenharmony_ci */
96cd6a6acSopenharmony_ci
106cd6a6acSopenharmony_ci#include <stdlib.h>
116cd6a6acSopenharmony_ci#include "queue.h"
126cd6a6acSopenharmony_ci
136cd6a6acSopenharmony_ciqueue_t queue_create(void)
146cd6a6acSopenharmony_ci{
156cd6a6acSopenharmony_ci	queue_t q;
166cd6a6acSopenharmony_ci
176cd6a6acSopenharmony_ci	q = (queue_t) malloc(sizeof(struct queue_info));
186cd6a6acSopenharmony_ci	if (q == NULL)
196cd6a6acSopenharmony_ci		return NULL;
206cd6a6acSopenharmony_ci
216cd6a6acSopenharmony_ci	q->head = q->tail = NULL;
226cd6a6acSopenharmony_ci
236cd6a6acSopenharmony_ci	return q;
246cd6a6acSopenharmony_ci}
256cd6a6acSopenharmony_ci
266cd6a6acSopenharmony_ciint queue_insert(queue_t q, queue_element_t e)
276cd6a6acSopenharmony_ci{
286cd6a6acSopenharmony_ci	queue_node_ptr_t newnode;
296cd6a6acSopenharmony_ci
306cd6a6acSopenharmony_ci	if (!q)
316cd6a6acSopenharmony_ci		return -1;
326cd6a6acSopenharmony_ci
336cd6a6acSopenharmony_ci	newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
346cd6a6acSopenharmony_ci	if (newnode == NULL)
356cd6a6acSopenharmony_ci		return -1;
366cd6a6acSopenharmony_ci
376cd6a6acSopenharmony_ci	newnode->element = e;
386cd6a6acSopenharmony_ci	newnode->next = NULL;
396cd6a6acSopenharmony_ci
406cd6a6acSopenharmony_ci	if (q->head == NULL) {
416cd6a6acSopenharmony_ci		q->head = q->tail = newnode;
426cd6a6acSopenharmony_ci	} else {
436cd6a6acSopenharmony_ci		q->tail->next = newnode;
446cd6a6acSopenharmony_ci		q->tail = newnode;
456cd6a6acSopenharmony_ci	}
466cd6a6acSopenharmony_ci
476cd6a6acSopenharmony_ci	return 0;
486cd6a6acSopenharmony_ci}
496cd6a6acSopenharmony_ci
506cd6a6acSopenharmony_ciint queue_push(queue_t q, queue_element_t e)
516cd6a6acSopenharmony_ci{
526cd6a6acSopenharmony_ci	queue_node_ptr_t newnode;
536cd6a6acSopenharmony_ci
546cd6a6acSopenharmony_ci	if (!q)
556cd6a6acSopenharmony_ci		return -1;
566cd6a6acSopenharmony_ci
576cd6a6acSopenharmony_ci	newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
586cd6a6acSopenharmony_ci	if (newnode == NULL)
596cd6a6acSopenharmony_ci		return -1;
606cd6a6acSopenharmony_ci
616cd6a6acSopenharmony_ci	newnode->element = e;
626cd6a6acSopenharmony_ci	newnode->next = NULL;
636cd6a6acSopenharmony_ci
646cd6a6acSopenharmony_ci	if (q->head == NULL) {
656cd6a6acSopenharmony_ci		q->head = q->tail = newnode;
666cd6a6acSopenharmony_ci	} else {
676cd6a6acSopenharmony_ci		newnode->next = q->head;
686cd6a6acSopenharmony_ci		q->head = newnode;
696cd6a6acSopenharmony_ci	}
706cd6a6acSopenharmony_ci
716cd6a6acSopenharmony_ci	return 0;
726cd6a6acSopenharmony_ci}
736cd6a6acSopenharmony_ci
746cd6a6acSopenharmony_ciqueue_element_t queue_remove(queue_t q)
756cd6a6acSopenharmony_ci{
766cd6a6acSopenharmony_ci	queue_node_ptr_t node;
776cd6a6acSopenharmony_ci	queue_element_t e;
786cd6a6acSopenharmony_ci
796cd6a6acSopenharmony_ci	if (!q)
806cd6a6acSopenharmony_ci		return NULL;
816cd6a6acSopenharmony_ci
826cd6a6acSopenharmony_ci	if (q->head == NULL)
836cd6a6acSopenharmony_ci		return NULL;
846cd6a6acSopenharmony_ci
856cd6a6acSopenharmony_ci	node = q->head;
866cd6a6acSopenharmony_ci	q->head = q->head->next;
876cd6a6acSopenharmony_ci	if (q->head == NULL)
886cd6a6acSopenharmony_ci		q->tail = NULL;
896cd6a6acSopenharmony_ci
906cd6a6acSopenharmony_ci	e = node->element;
916cd6a6acSopenharmony_ci	free(node);
926cd6a6acSopenharmony_ci
936cd6a6acSopenharmony_ci	return e;
946cd6a6acSopenharmony_ci}
956cd6a6acSopenharmony_ci
966cd6a6acSopenharmony_ciqueue_element_t queue_head(queue_t q)
976cd6a6acSopenharmony_ci{
986cd6a6acSopenharmony_ci	if (!q)
996cd6a6acSopenharmony_ci		return NULL;
1006cd6a6acSopenharmony_ci
1016cd6a6acSopenharmony_ci	if (q->head == NULL)
1026cd6a6acSopenharmony_ci		return NULL;
1036cd6a6acSopenharmony_ci
1046cd6a6acSopenharmony_ci	return q->head->element;
1056cd6a6acSopenharmony_ci}
1066cd6a6acSopenharmony_ci
1076cd6a6acSopenharmony_civoid queue_destroy(queue_t q)
1086cd6a6acSopenharmony_ci{
1096cd6a6acSopenharmony_ci	queue_node_ptr_t p, temp;
1106cd6a6acSopenharmony_ci
1116cd6a6acSopenharmony_ci	if (!q)
1126cd6a6acSopenharmony_ci		return;
1136cd6a6acSopenharmony_ci
1146cd6a6acSopenharmony_ci	p = q->head;
1156cd6a6acSopenharmony_ci	while (p != NULL) {
1166cd6a6acSopenharmony_ci		free(p->element);
1176cd6a6acSopenharmony_ci		temp = p;
1186cd6a6acSopenharmony_ci		p = p->next;
1196cd6a6acSopenharmony_ci		free(temp);
1206cd6a6acSopenharmony_ci	}
1216cd6a6acSopenharmony_ci
1226cd6a6acSopenharmony_ci	free(q);
1236cd6a6acSopenharmony_ci}
1246cd6a6acSopenharmony_ci
1256cd6a6acSopenharmony_ciint queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp)
1266cd6a6acSopenharmony_ci{
1276cd6a6acSopenharmony_ci	queue_node_ptr_t p;
1286cd6a6acSopenharmony_ci	int ret;
1296cd6a6acSopenharmony_ci
1306cd6a6acSopenharmony_ci	if (!q)
1316cd6a6acSopenharmony_ci		return 0;
1326cd6a6acSopenharmony_ci
1336cd6a6acSopenharmony_ci	p = q->head;
1346cd6a6acSopenharmony_ci	while (p != NULL) {
1356cd6a6acSopenharmony_ci		ret = f(p->element, vp);
1366cd6a6acSopenharmony_ci		if (ret)
1376cd6a6acSopenharmony_ci			return ret;
1386cd6a6acSopenharmony_ci		p = p->next;
1396cd6a6acSopenharmony_ci	}
1406cd6a6acSopenharmony_ci	return 0;
1416cd6a6acSopenharmony_ci}
1426cd6a6acSopenharmony_ci
1436cd6a6acSopenharmony_civoid queue_map_remove_on_error(queue_t q,
1446cd6a6acSopenharmony_ci			       int (*f) (queue_element_t, void *),
1456cd6a6acSopenharmony_ci			       void (*g) (queue_element_t, void *), void *vp)
1466cd6a6acSopenharmony_ci{
1476cd6a6acSopenharmony_ci	queue_node_ptr_t p, last, temp;
1486cd6a6acSopenharmony_ci	int ret;
1496cd6a6acSopenharmony_ci
1506cd6a6acSopenharmony_ci	if (!q)
1516cd6a6acSopenharmony_ci		return;
1526cd6a6acSopenharmony_ci
1536cd6a6acSopenharmony_ci	last = NULL;
1546cd6a6acSopenharmony_ci	p = q->head;
1556cd6a6acSopenharmony_ci	while (p != NULL) {
1566cd6a6acSopenharmony_ci		ret = f(p->element, vp);
1576cd6a6acSopenharmony_ci		if (ret) {
1586cd6a6acSopenharmony_ci			if (last) {
1596cd6a6acSopenharmony_ci				last->next = p->next;
1606cd6a6acSopenharmony_ci				if (last->next == NULL)
1616cd6a6acSopenharmony_ci					q->tail = last;
1626cd6a6acSopenharmony_ci			} else {
1636cd6a6acSopenharmony_ci				q->head = p->next;
1646cd6a6acSopenharmony_ci				if (q->head == NULL)
1656cd6a6acSopenharmony_ci					q->tail = NULL;
1666cd6a6acSopenharmony_ci			}
1676cd6a6acSopenharmony_ci
1686cd6a6acSopenharmony_ci			temp = p;
1696cd6a6acSopenharmony_ci			p = p->next;
1706cd6a6acSopenharmony_ci			g(temp->element, vp);
1716cd6a6acSopenharmony_ci			free(temp);
1726cd6a6acSopenharmony_ci		} else {
1736cd6a6acSopenharmony_ci			last = p;
1746cd6a6acSopenharmony_ci			p = p->next;
1756cd6a6acSopenharmony_ci		}
1766cd6a6acSopenharmony_ci	}
1776cd6a6acSopenharmony_ci
1786cd6a6acSopenharmony_ci	return;
1796cd6a6acSopenharmony_ci}
1806cd6a6acSopenharmony_ci
1816cd6a6acSopenharmony_ci/* FLASK */
182