]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Boost.Wave: A Standard compliant C++ preprocessor library | |
3 | http://www.boost.org/ | |
4 | ||
5 | Copyright (c) 2001 Daniel C. Nuffer. | |
b32b8144 FG |
6 | Copyright (c) 2001-2012 Hartmut Kaiser. |
7 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
7c673cae FG |
8 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9 | =============================================================================*/ | |
10 | ||
11 | #define BOOST_WAVE_SOURCE 1 | |
12 | ||
13 | // disable stupid compiler warnings | |
14 | #include <boost/config/warning_disable.hpp> | |
15 | ||
16 | #include <cstdlib> | |
17 | #include <cstring> | |
18 | ||
19 | #include <boost/wave/wave_config.hpp> // configuration data | |
20 | #include <boost/wave/cpplexer/re2clex/aq.hpp> | |
21 | ||
22 | #include <boost/assert.hpp> | |
23 | ||
24 | // this must occur after all of the includes and before any code appears | |
25 | #ifdef BOOST_HAS_ABI_HEADERS | |
26 | #include BOOST_ABI_PREFIX | |
27 | #endif | |
28 | ||
29 | /////////////////////////////////////////////////////////////////////////////// | |
30 | namespace boost { | |
31 | namespace wave { | |
32 | namespace cpplexer { | |
33 | namespace re2clex { | |
34 | ||
35 | int aq_grow(aq_queue q) | |
36 | { | |
37 | using namespace std; // some systems have memcpy/realloc in std | |
38 | std::size_t new_size = q->max_size << 1; | |
39 | aq_stdelement* new_queue = (aq_stdelement*)realloc(q->queue, | |
40 | new_size * sizeof(aq_stdelement)); | |
41 | ||
42 | BOOST_ASSERT(NULL != q); | |
43 | BOOST_ASSERT(q->max_size < 100000); | |
44 | BOOST_ASSERT(q->size <= q->max_size); | |
45 | ||
46 | #define ASSERT_SIZE BOOST_ASSERT( \ | |
47 | ((q->tail + q->max_size + 1) - q->head) % q->max_size == \ | |
48 | q->size % q->max_size) | |
49 | ||
50 | ASSERT_SIZE; | |
51 | BOOST_ASSERT(q->head <= q->max_size); | |
52 | BOOST_ASSERT(q->tail <= q->max_size); | |
53 | ||
54 | if (!new_queue) | |
55 | { | |
56 | BOOST_ASSERT(0); | |
57 | return 0; | |
58 | } | |
59 | ||
60 | q->queue = new_queue; | |
61 | if (q->tail <= q->head) /* tail has wrapped around */ | |
62 | { | |
63 | /* move the tail from the beginning to the end */ | |
64 | memcpy(q->queue + q->max_size, q->queue, | |
65 | (q->tail + 1) * sizeof(aq_stdelement)); | |
66 | q->tail += q->max_size; | |
67 | } | |
68 | q->max_size = new_size; | |
69 | ||
70 | BOOST_ASSERT(q->size <= q->max_size); | |
71 | ASSERT_SIZE; | |
72 | BOOST_ASSERT(q->head <= q->max_size); | |
73 | BOOST_ASSERT(q->tail <= q->max_size); | |
74 | ||
75 | return 1; | |
76 | } | |
77 | ||
78 | int aq_enqueue(aq_queue q, aq_stdelement e) | |
79 | { | |
80 | BOOST_ASSERT(NULL != q); | |
81 | BOOST_ASSERT(q->size <= q->max_size); | |
82 | ASSERT_SIZE; | |
83 | BOOST_ASSERT(q->head <= q->max_size); | |
84 | BOOST_ASSERT(q->tail <= q->max_size); | |
85 | ||
86 | ||
87 | if (AQ_FULL(q)) | |
88 | if (!aq_grow(q)) | |
89 | return 0; | |
90 | ||
91 | ++q->tail; | |
92 | if (q->tail == q->max_size) | |
93 | q->tail = 0; | |
94 | ||
95 | q->queue[q->tail] = e; | |
96 | ++q->size; | |
97 | ||
98 | BOOST_ASSERT(q->size <= q->max_size); | |
99 | ASSERT_SIZE; | |
100 | BOOST_ASSERT(q->head <= q->max_size); | |
101 | BOOST_ASSERT(q->tail <= q->max_size); | |
102 | ||
103 | return 1; | |
104 | } | |
105 | ||
106 | int aq_enqueue_front(aq_queue q, aq_stdelement e) | |
107 | { | |
108 | BOOST_ASSERT(NULL != q); | |
109 | ||
110 | BOOST_ASSERT(q->size <= q->max_size); | |
111 | ASSERT_SIZE; | |
112 | BOOST_ASSERT(q->head <= q->max_size); | |
113 | BOOST_ASSERT(q->tail <= q->max_size); | |
114 | ||
115 | ||
116 | if (AQ_FULL(q)) | |
117 | if (!aq_grow(q)) | |
118 | return 0; | |
119 | ||
120 | if (q->head == 0) | |
121 | q->head = q->max_size - 1; | |
122 | else | |
123 | --q->head; | |
124 | ||
125 | q->queue[q->head] = e; | |
126 | ++q->size; | |
127 | ||
128 | BOOST_ASSERT(q->size <= q->max_size); | |
129 | ASSERT_SIZE; | |
130 | BOOST_ASSERT(q->head <= q->max_size); | |
131 | BOOST_ASSERT(q->tail <= q->max_size); | |
132 | ||
133 | return 1; | |
134 | } | |
135 | ||
136 | int aq_serve(aq_queue q, aq_stdelement *e) | |
137 | { | |
138 | ||
139 | BOOST_ASSERT(NULL != q); | |
140 | BOOST_ASSERT(q->size <= q->max_size); | |
141 | ASSERT_SIZE; | |
142 | BOOST_ASSERT(q->head <= q->max_size); | |
143 | BOOST_ASSERT(q->tail <= q->max_size); | |
144 | ||
145 | ||
146 | if (AQ_EMPTY(q)) | |
147 | return 0; | |
148 | ||
149 | *e = q->queue[q->head]; | |
150 | return aq_pop(q); | |
151 | } | |
152 | ||
153 | int aq_pop(aq_queue q) | |
154 | { | |
155 | ||
156 | BOOST_ASSERT(NULL != q); | |
157 | BOOST_ASSERT(q->size <= q->max_size); | |
158 | ASSERT_SIZE; | |
159 | BOOST_ASSERT(q->head <= q->max_size); | |
160 | BOOST_ASSERT(q->tail <= q->max_size); | |
161 | ||
162 | ||
163 | if (AQ_EMPTY(q)) | |
164 | return 0; | |
165 | ||
166 | ++q->head; | |
167 | if (q->head == q->max_size) | |
168 | q->head = 0; | |
169 | --q->size; | |
170 | ||
171 | BOOST_ASSERT(q->size <= q->max_size); | |
172 | ASSERT_SIZE; | |
173 | BOOST_ASSERT(q->head <= q->max_size); | |
174 | BOOST_ASSERT(q->tail <= q->max_size); | |
175 | ||
176 | return 1; | |
177 | } | |
178 | ||
179 | aq_queue aq_create(void) | |
180 | { | |
181 | aq_queue q; | |
182 | ||
183 | using namespace std; // some systems have malloc in std | |
184 | q = (aq_queue)malloc(sizeof(aq_queuetype)); | |
185 | if (!q) | |
186 | { | |
187 | return 0; | |
188 | } | |
189 | ||
190 | q->max_size = 8; /* initial size */ | |
191 | q->queue = (aq_stdelement*)malloc( | |
192 | sizeof(aq_stdelement) * q->max_size); | |
193 | if (!q->queue) | |
194 | { | |
195 | free(q); | |
196 | return 0; | |
197 | } | |
198 | ||
199 | q->head = 0; | |
200 | q->tail = q->max_size - 1; | |
201 | q->size = 0; | |
202 | ||
203 | ||
204 | BOOST_ASSERT(q->size <= q->max_size); | |
205 | ASSERT_SIZE; | |
206 | BOOST_ASSERT(q->head <= q->max_size); | |
207 | BOOST_ASSERT(q->tail <= q->max_size); | |
208 | ||
209 | return q; | |
210 | } | |
211 | ||
212 | void aq_terminate(aq_queue q) | |
213 | { | |
214 | using namespace std; // some systems have free in std | |
215 | ||
216 | BOOST_ASSERT(NULL != q); | |
217 | BOOST_ASSERT(q->size <= q->max_size); | |
218 | ASSERT_SIZE; | |
219 | BOOST_ASSERT(q->head <= q->max_size); | |
220 | BOOST_ASSERT(q->tail <= q->max_size); | |
221 | ||
222 | free(q->queue); | |
223 | free(q); | |
224 | } | |
225 | ||
226 | /////////////////////////////////////////////////////////////////////////////// | |
227 | } // namespace re2clex | |
228 | } // namespace cpplexer | |
229 | } // namespace wave | |
230 | } // namespace boost | |
231 | ||
232 | // the suffix header occurs after all of the code | |
233 | #ifdef BOOST_HAS_ABI_HEADERS | |
234 | #include BOOST_ABI_SUFFIX | |
235 | #endif | |
236 |