• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */
3 
4 /* FLASK */
5 
6 /*
7  * Implementation of the double-ended queue type.
8  */
9 
10 #include <stdlib.h>
11 #include "queue.h"
12 
queue_create(void)13 queue_t queue_create(void)
14 {
15 	queue_t q;
16 
17 	q = (queue_t) malloc(sizeof(struct queue_info));
18 	if (q == NULL)
19 		return NULL;
20 
21 	q->head = q->tail = NULL;
22 
23 	return q;
24 }
25 
queue_insert(queue_t q,queue_element_t e)26 int queue_insert(queue_t q, queue_element_t e)
27 {
28 	queue_node_ptr_t newnode;
29 
30 	if (!q)
31 		return -1;
32 
33 	newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
34 	if (newnode == NULL)
35 		return -1;
36 
37 	newnode->element = e;
38 	newnode->next = NULL;
39 
40 	if (q->head == NULL) {
41 		q->head = q->tail = newnode;
42 	} else {
43 		q->tail->next = newnode;
44 		q->tail = newnode;
45 	}
46 
47 	return 0;
48 }
49 
queue_push(queue_t q,queue_element_t e)50 int queue_push(queue_t q, queue_element_t e)
51 {
52 	queue_node_ptr_t newnode;
53 
54 	if (!q)
55 		return -1;
56 
57 	newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
58 	if (newnode == NULL)
59 		return -1;
60 
61 	newnode->element = e;
62 	newnode->next = NULL;
63 
64 	if (q->head == NULL) {
65 		q->head = q->tail = newnode;
66 	} else {
67 		newnode->next = q->head;
68 		q->head = newnode;
69 	}
70 
71 	return 0;
72 }
73 
queue_remove(queue_t q)74 queue_element_t queue_remove(queue_t q)
75 {
76 	queue_node_ptr_t node;
77 	queue_element_t e;
78 
79 	if (!q)
80 		return NULL;
81 
82 	if (q->head == NULL)
83 		return NULL;
84 
85 	node = q->head;
86 	q->head = q->head->next;
87 	if (q->head == NULL)
88 		q->tail = NULL;
89 
90 	e = node->element;
91 	free(node);
92 
93 	return e;
94 }
95 
queue_head(queue_t q)96 queue_element_t queue_head(queue_t q)
97 {
98 	if (!q)
99 		return NULL;
100 
101 	if (q->head == NULL)
102 		return NULL;
103 
104 	return q->head->element;
105 }
106 
queue_destroy(queue_t q)107 void queue_destroy(queue_t q)
108 {
109 	queue_node_ptr_t p, temp;
110 
111 	if (!q)
112 		return;
113 
114 	p = q->head;
115 	while (p != NULL) {
116 		free(p->element);
117 		temp = p;
118 		p = p->next;
119 		free(temp);
120 	}
121 
122 	free(q);
123 }
124 
queue_map(queue_t q,int (* f)(queue_element_t,void *),void * vp)125 int queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp)
126 {
127 	queue_node_ptr_t p;
128 	int ret;
129 
130 	if (!q)
131 		return 0;
132 
133 	p = q->head;
134 	while (p != NULL) {
135 		ret = f(p->element, vp);
136 		if (ret)
137 			return ret;
138 		p = p->next;
139 	}
140 	return 0;
141 }
142 
queue_map_remove_on_error(queue_t q,int (* f)(queue_element_t,void *),void (* g)(queue_element_t,void *),void * vp)143 void queue_map_remove_on_error(queue_t q,
144 			       int (*f) (queue_element_t, void *),
145 			       void (*g) (queue_element_t, void *), void *vp)
146 {
147 	queue_node_ptr_t p, last, temp;
148 	int ret;
149 
150 	if (!q)
151 		return;
152 
153 	last = NULL;
154 	p = q->head;
155 	while (p != NULL) {
156 		ret = f(p->element, vp);
157 		if (ret) {
158 			if (last) {
159 				last->next = p->next;
160 				if (last->next == NULL)
161 					q->tail = last;
162 			} else {
163 				q->head = p->next;
164 				if (q->head == NULL)
165 					q->tail = NULL;
166 			}
167 
168 			temp = p;
169 			p = p->next;
170 			g(temp->element, vp);
171 			free(temp);
172 		} else {
173 			last = p;
174 			p = p->next;
175 		}
176 	}
177 
178 	return;
179 }
180 
181 /* FLASK */
182