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 temp = p;
117 p = p->next;
118 free(temp);
119 }
120
121 free(q);
122 }
123
queue_map(queue_t q,int (* f)(queue_element_t,void *),void * vp)124 int queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp)
125 {
126 queue_node_ptr_t p;
127 int ret;
128
129 if (!q)
130 return 0;
131
132 p = q->head;
133 while (p != NULL) {
134 ret = f(p->element, vp);
135 if (ret)
136 return ret;
137 p = p->next;
138 }
139 return 0;
140 }
141
queue_map_remove_on_error(queue_t q,int (* f)(queue_element_t,void *),void (* g)(queue_element_t,void *),void * vp)142 void queue_map_remove_on_error(queue_t q,
143 int (*f) (queue_element_t, void *),
144 void (*g) (queue_element_t, void *), void *vp)
145 {
146 queue_node_ptr_t p, last, temp;
147 int ret;
148
149 if (!q)
150 return;
151
152 last = NULL;
153 p = q->head;
154 while (p != NULL) {
155 ret = f(p->element, vp);
156 if (ret) {
157 if (last) {
158 last->next = p->next;
159 if (last->next == NULL)
160 q->tail = last;
161 } else {
162 q->head = p->next;
163 if (q->head == NULL)
164 q->tail = NULL;
165 }
166
167 temp = p;
168 p = p->next;
169 g(temp->element, vp);
170 free(temp);
171 } else {
172 last = p;
173 p = p->next;
174 }
175 }
176
177 return;
178 }
179
180 /* FLASK */
181