blob: 82e667328b2f44fc368dae5f98dc260c4f898732 [file] [log] [blame]
Joshua Brindle13cd4c82008-08-19 15:30:36 -04001
Stephen Smalley53bb2a12017-08-17 14:16:06 -04002/* Author : Stephen Smalley, <sds@tycho.nsa.gov> */
Joshua Brindle13cd4c82008-08-19 15:30:36 -04003
4/* FLASK */
5
6/*
7 * Implementation of the double-ended queue type.
8 */
9
10#include <stdlib.h>
11#include "queue.h"
12
13queue_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
26int 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
50int 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
74queue_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
96queue_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
107void 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) {
Nicolas Iooss47f61b02016-12-26 22:18:31 +0100116 free(p->element);
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400117 temp = p;
118 p = p->next;
119 free(temp);
120 }
121
122 free(q);
123}
124
125int 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
143void 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 */