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