obstack.h revision 1.9 1 1.1 christos /* obstack.h - object stack macros
2 1.9 christos Copyright (C) 1988-2024 Free Software Foundation, Inc.
3 1.3 christos This file is part of the GNU C Library.
4 1.1 christos
5 1.3 christos The GNU C Library is free software; you can redistribute it and/or
6 1.3 christos modify it under the terms of the GNU Lesser General Public
7 1.3 christos License as published by the Free Software Foundation; either
8 1.3 christos version 2.1 of the License, or (at your option) any later version.
9 1.1 christos
10 1.3 christos The GNU C Library is distributed in the hope that it will be useful,
11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1.3 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 1.3 christos Lesser General Public License for more details.
14 1.1 christos
15 1.3 christos You should have received a copy of the GNU Lesser General Public
16 1.3 christos License along with the GNU C Library; if not, see
17 1.3 christos <http://www.gnu.org/licenses/>. */
18 1.1 christos
19 1.1 christos /* Summary:
20 1.1 christos
21 1.3 christos All the apparent functions defined here are macros. The idea
22 1.3 christos is that you would use these pre-tested macros to solve a
23 1.3 christos very specific set of problems, and they would run fast.
24 1.3 christos Caution: no side-effects in arguments please!! They may be
25 1.3 christos evaluated MANY times!!
26 1.3 christos
27 1.3 christos These macros operate a stack of objects. Each object starts life
28 1.3 christos small, and may grow to maturity. (Consider building a word syllable
29 1.3 christos by syllable.) An object can move while it is growing. Once it has
30 1.3 christos been "finished" it never changes address again. So the "top of the
31 1.3 christos stack" is typically an immature growing object, while the rest of the
32 1.3 christos stack is of mature, fixed size and fixed address objects.
33 1.3 christos
34 1.3 christos These routines grab large chunks of memory, using a function you
35 1.3 christos supply, called 'obstack_chunk_alloc'. On occasion, they free chunks,
36 1.3 christos by calling 'obstack_chunk_free'. You must define them and declare
37 1.3 christos them before using any obstack macros.
38 1.3 christos
39 1.3 christos Each independent stack is represented by a 'struct obstack'.
40 1.3 christos Each of the obstack macros expects a pointer to such a structure
41 1.3 christos as the first argument.
42 1.3 christos
43 1.3 christos One motivation for this package is the problem of growing char strings
44 1.3 christos in symbol tables. Unless you are "fascist pig with a read-only mind"
45 1.3 christos --Gosper's immortal quote from HAKMEM item 154, out of context--you
46 1.3 christos would not like to put any arbitrary upper limit on the length of your
47 1.3 christos symbols.
48 1.3 christos
49 1.3 christos In practice this often means you will build many short symbols and a
50 1.3 christos few long symbols. At the time you are reading a symbol you don't know
51 1.3 christos how long it is. One traditional method is to read a symbol into a
52 1.3 christos buffer, realloc()ating the buffer every time you try to read a symbol
53 1.3 christos that is longer than the buffer. This is beaut, but you still will
54 1.3 christos want to copy the symbol from the buffer to a more permanent
55 1.3 christos symbol-table entry say about half the time.
56 1.3 christos
57 1.3 christos With obstacks, you can work differently. Use one obstack for all symbol
58 1.3 christos names. As you read a symbol, grow the name in the obstack gradually.
59 1.3 christos When the name is complete, finalize it. Then, if the symbol exists already,
60 1.3 christos free the newly read name.
61 1.3 christos
62 1.3 christos The way we do this is to take a large chunk, allocating memory from
63 1.3 christos low addresses. When you want to build a symbol in the chunk you just
64 1.3 christos add chars above the current "high water mark" in the chunk. When you
65 1.3 christos have finished adding chars, because you got to the end of the symbol,
66 1.3 christos you know how long the chars are, and you can create a new object.
67 1.3 christos Mostly the chars will not burst over the highest address of the chunk,
68 1.3 christos because you would typically expect a chunk to be (say) 100 times as
69 1.3 christos long as an average object.
70 1.3 christos
71 1.3 christos In case that isn't clear, when we have enough chars to make up
72 1.3 christos the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
73 1.3 christos so we just point to it where it lies. No moving of chars is
74 1.3 christos needed and this is the second win: potentially long strings need
75 1.3 christos never be explicitly shuffled. Once an object is formed, it does not
76 1.3 christos change its address during its lifetime.
77 1.3 christos
78 1.3 christos When the chars burst over a chunk boundary, we allocate a larger
79 1.3 christos chunk, and then copy the partly formed object from the end of the old
80 1.3 christos chunk to the beginning of the new larger chunk. We then carry on
81 1.3 christos accreting characters to the end of the object as we normally would.
82 1.3 christos
83 1.3 christos A special macro is provided to add a single char at a time to a
84 1.3 christos growing object. This allows the use of register variables, which
85 1.3 christos break the ordinary 'growth' macro.
86 1.3 christos
87 1.3 christos Summary:
88 1.3 christos We allocate large chunks.
89 1.3 christos We carve out one object at a time from the current chunk.
90 1.3 christos Once carved, an object never moves.
91 1.3 christos We are free to append data of any size to the currently
92 1.3 christos growing object.
93 1.3 christos Exactly one object is growing in an obstack at any one time.
94 1.3 christos You can run one obstack per control block.
95 1.3 christos You may have as many control blocks as you dare.
96 1.3 christos Because of the way we do it, you can "unwind" an obstack
97 1.3 christos back to a previous state. (You may remove objects much
98 1.3 christos as you would with a stack.)
99 1.3 christos */
100 1.1 christos
101 1.1 christos
102 1.1 christos /* Don't do the contents of this file more than once. */
103 1.1 christos
104 1.1 christos #ifndef _OBSTACK_H
105 1.1 christos #define _OBSTACK_H 1
106 1.1 christos
107 1.3 christos #ifndef _OBSTACK_INTERFACE_VERSION
108 1.3 christos # define _OBSTACK_INTERFACE_VERSION 2
109 1.1 christos #endif
110 1.1 christos
111 1.3 christos #include <stddef.h> /* For size_t and ptrdiff_t. */
112 1.3 christos #include <string.h> /* For __GNU_LIBRARY__, and memcpy. */
113 1.1 christos
114 1.3 christos #if _OBSTACK_INTERFACE_VERSION == 1
115 1.3 christos /* For binary compatibility with obstack version 1, which used "int"
116 1.3 christos and "long" for these two types. */
117 1.3 christos # define _OBSTACK_SIZE_T unsigned int
118 1.3 christos # define _CHUNK_SIZE_T unsigned long
119 1.3 christos # define _OBSTACK_CAST(type, expr) ((type) (expr))
120 1.3 christos #else
121 1.3 christos /* Version 2 with sane types, especially for 64-bit hosts. */
122 1.3 christos # define _OBSTACK_SIZE_T size_t
123 1.3 christos # define _CHUNK_SIZE_T size_t
124 1.3 christos # define _OBSTACK_CAST(type, expr) (expr)
125 1.1 christos #endif
126 1.1 christos
127 1.3 christos /* If B is the base of an object addressed by P, return the result of
128 1.3 christos aligning P to the next multiple of A + 1. B and P must be of type
129 1.3 christos char *. A + 1 must be a power of 2. */
130 1.3 christos
131 1.3 christos #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
132 1.3 christos
133 1.3 christos /* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
134 1.3 christos where pointers can be converted to integers, aligned as integers,
135 1.3 christos and converted back again. If ptrdiff_t is narrower than a
136 1.3 christos pointer (e.g., the AS/400), play it safe and compute the alignment
137 1.3 christos relative to B. Otherwise, use the faster strategy of computing the
138 1.3 christos alignment relative to 0. */
139 1.3 christos
140 1.8 christos #define __PTR_ALIGN(B, P, A) \
141 1.8 christos (sizeof (ptrdiff_t) < sizeof (void *) ? __BPTR_ALIGN (B, P, A) \
142 1.8 christos : (char *) (((ptrdiff_t) (P) + (A)) & ~(A)))
143 1.3 christos
144 1.3 christos #ifndef __attribute_pure__
145 1.3 christos # if defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2096
146 1.3 christos # define __attribute_pure__ __attribute__ ((__pure__))
147 1.1 christos # else
148 1.3 christos # define __attribute_pure__
149 1.1 christos # endif
150 1.1 christos #endif
151 1.1 christos
152 1.3 christos #ifdef __cplusplus
153 1.3 christos extern "C" {
154 1.1 christos #endif
155 1.1 christos
156 1.3 christos struct _obstack_chunk /* Lives at front of each chunk. */
157 1.1 christos {
158 1.3 christos char *limit; /* 1 past end of this chunk */
159 1.3 christos struct _obstack_chunk *prev; /* address of prior chunk or NULL */
160 1.3 christos char contents[4]; /* objects begin here */
161 1.1 christos };
162 1.1 christos
163 1.3 christos struct obstack /* control current object in current chunk */
164 1.1 christos {
165 1.3 christos _CHUNK_SIZE_T chunk_size; /* preferred size to allocate chunks in */
166 1.3 christos struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
167 1.3 christos char *object_base; /* address of object we are building */
168 1.3 christos char *next_free; /* where to add next char to current object */
169 1.3 christos char *chunk_limit; /* address of char after current chunk */
170 1.3 christos union
171 1.3 christos {
172 1.3 christos _OBSTACK_SIZE_T i;
173 1.3 christos void *p;
174 1.3 christos } temp; /* Temporary for some macros. */
175 1.3 christos _OBSTACK_SIZE_T alignment_mask; /* Mask of alignment for each object. */
176 1.3 christos
177 1.3 christos /* These prototypes vary based on 'use_extra_arg'. */
178 1.3 christos union
179 1.3 christos {
180 1.3 christos void *(*plain) (size_t);
181 1.3 christos void *(*extra) (void *, size_t);
182 1.3 christos } chunkfun;
183 1.3 christos union
184 1.3 christos {
185 1.3 christos void (*plain) (void *);
186 1.3 christos void (*extra) (void *, void *);
187 1.3 christos } freefun;
188 1.3 christos
189 1.3 christos void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
190 1.3 christos unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */
191 1.3 christos unsigned maybe_empty_object : 1; /* There is a possibility that the current
192 1.3 christos chunk contains a zero-length object. This
193 1.3 christos prevents freeing the chunk if we allocate
194 1.3 christos a bigger chunk to replace it. */
195 1.3 christos unsigned alloc_failed : 1; /* No longer used, as we now call the failed
196 1.3 christos handler on error, but retained for binary
197 1.3 christos compatibility. */
198 1.1 christos };
199 1.1 christos
200 1.1 christos /* Declare the external functions we use; they are in obstack.c. */
201 1.1 christos
202 1.3 christos extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
203 1.1 christos extern void _obstack_free (struct obstack *, void *);
204 1.3 christos extern int _obstack_begin (struct obstack *,
205 1.3 christos _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
206 1.3 christos void *(*) (size_t), void (*) (void *));
207 1.3 christos extern int _obstack_begin_1 (struct obstack *,
208 1.3 christos _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
209 1.3 christos void *(*) (void *, size_t),
210 1.3 christos void (*) (void *, void *), void *);
211 1.3 christos extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
212 1.3 christos __attribute_pure__;
213 1.3 christos
214 1.3 christos
215 1.3 christos /* Error handler called when 'obstack_chunk_alloc' failed to allocate
216 1.3 christos more memory. This can be set to a user defined function which
217 1.3 christos should either abort gracefully or use longjump - but shouldn't
218 1.3 christos return. The default action is to print a message and abort. */
219 1.1 christos extern void (*obstack_alloc_failed_handler) (void);
220 1.1 christos
221 1.3 christos /* Exit value used when 'print_and_abort' is used. */
222 1.1 christos extern int obstack_exit_failure;
223 1.3 christos
224 1.1 christos /* Pointer to beginning of object being allocated or to be allocated next.
225 1.1 christos Note that this might not be the final address of the object
226 1.1 christos because a new chunk might be needed to hold the final size. */
227 1.1 christos
228 1.3 christos #define obstack_base(h) ((void *) (h)->object_base)
229 1.1 christos
230 1.1 christos /* Size for allocating ordinary chunks. */
231 1.1 christos
232 1.1 christos #define obstack_chunk_size(h) ((h)->chunk_size)
233 1.1 christos
234 1.1 christos /* Pointer to next byte not yet allocated in current chunk. */
235 1.1 christos
236 1.3 christos #define obstack_next_free(h) ((void *) (h)->next_free)
237 1.1 christos
238 1.1 christos /* Mask specifying low bits that should be clear in address of an object. */
239 1.1 christos
240 1.1 christos #define obstack_alignment_mask(h) ((h)->alignment_mask)
241 1.1 christos
242 1.3 christos /* To prevent prototype warnings provide complete argument list. */
243 1.3 christos #define obstack_init(h) \
244 1.3 christos _obstack_begin ((h), 0, 0, \
245 1.3 christos _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
246 1.3 christos _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
247 1.3 christos
248 1.3 christos #define obstack_begin(h, size) \
249 1.3 christos _obstack_begin ((h), (size), 0, \
250 1.3 christos _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
251 1.3 christos _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
252 1.3 christos
253 1.3 christos #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
254 1.3 christos _obstack_begin ((h), (size), (alignment), \
255 1.3 christos _OBSTACK_CAST (void *(*) (size_t), chunkfun), \
256 1.3 christos _OBSTACK_CAST (void (*) (void *), freefun))
257 1.3 christos
258 1.3 christos #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
259 1.3 christos _obstack_begin_1 ((h), (size), (alignment), \
260 1.3 christos _OBSTACK_CAST (void *(*) (void *, size_t), chunkfun), \
261 1.3 christos _OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
262 1.3 christos
263 1.3 christos #define obstack_chunkfun(h, newchunkfun) \
264 1.3 christos ((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun)))
265 1.1 christos
266 1.3 christos #define obstack_freefun(h, newfreefun) \
267 1.3 christos ((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun)))
268 1.1 christos
269 1.3 christos #define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
270 1.1 christos
271 1.3 christos #define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
272 1.1 christos
273 1.1 christos #define obstack_memory_used(h) _obstack_memory_used (h)
274 1.3 christos
275 1.3 christos #if defined __GNUC__
276 1.3 christos # if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008
277 1.1 christos # define __extension__
278 1.1 christos # endif
279 1.1 christos
280 1.1 christos /* For GNU C, if not -traditional,
281 1.1 christos we can define these macros to compute all args only once
282 1.1 christos without using a global variable.
283 1.3 christos Also, we can avoid using the 'temp' slot, to make faster code. */
284 1.1 christos
285 1.3 christos # define obstack_object_size(OBSTACK) \
286 1.3 christos __extension__ \
287 1.3 christos ({ struct obstack const *__o = (OBSTACK); \
288 1.3 christos (_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); })
289 1.3 christos
290 1.3 christos /* The local variable is named __o1 to avoid a shadowed variable
291 1.3 christos warning when invoked from other obstack macros. */
292 1.3 christos # define obstack_room(OBSTACK) \
293 1.3 christos __extension__ \
294 1.3 christos ({ struct obstack const *__o1 = (OBSTACK); \
295 1.3 christos (_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); })
296 1.3 christos
297 1.3 christos # define obstack_make_room(OBSTACK, length) \
298 1.3 christos __extension__ \
299 1.3 christos ({ struct obstack *__o = (OBSTACK); \
300 1.3 christos _OBSTACK_SIZE_T __len = (length); \
301 1.3 christos if (obstack_room (__o) < __len) \
302 1.3 christos _obstack_newchunk (__o, __len); \
303 1.3 christos (void) 0; })
304 1.3 christos
305 1.3 christos # define obstack_empty_p(OBSTACK) \
306 1.3 christos __extension__ \
307 1.3 christos ({ struct obstack const *__o = (OBSTACK); \
308 1.3 christos (__o->chunk->prev == 0 \
309 1.3 christos && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
310 1.3 christos __o->chunk->contents, \
311 1.3 christos __o->alignment_mask)); })
312 1.3 christos
313 1.3 christos # define obstack_grow(OBSTACK, where, length) \
314 1.3 christos __extension__ \
315 1.3 christos ({ struct obstack *__o = (OBSTACK); \
316 1.3 christos _OBSTACK_SIZE_T __len = (length); \
317 1.3 christos if (obstack_room (__o) < __len) \
318 1.3 christos _obstack_newchunk (__o, __len); \
319 1.3 christos memcpy (__o->next_free, where, __len); \
320 1.3 christos __o->next_free += __len; \
321 1.3 christos (void) 0; })
322 1.3 christos
323 1.3 christos # define obstack_grow0(OBSTACK, where, length) \
324 1.3 christos __extension__ \
325 1.3 christos ({ struct obstack *__o = (OBSTACK); \
326 1.3 christos _OBSTACK_SIZE_T __len = (length); \
327 1.3 christos if (obstack_room (__o) < __len + 1) \
328 1.3 christos _obstack_newchunk (__o, __len + 1); \
329 1.3 christos memcpy (__o->next_free, where, __len); \
330 1.3 christos __o->next_free += __len; \
331 1.3 christos *(__o->next_free)++ = 0; \
332 1.3 christos (void) 0; })
333 1.3 christos
334 1.3 christos # define obstack_1grow(OBSTACK, datum) \
335 1.3 christos __extension__ \
336 1.3 christos ({ struct obstack *__o = (OBSTACK); \
337 1.3 christos if (obstack_room (__o) < 1) \
338 1.3 christos _obstack_newchunk (__o, 1); \
339 1.3 christos obstack_1grow_fast (__o, datum); })
340 1.1 christos
341 1.3 christos /* These assume that the obstack alignment is good enough for pointers
342 1.3 christos or ints, and that the data added so far to the current object
343 1.1 christos shares that much alignment. */
344 1.1 christos
345 1.3 christos # define obstack_ptr_grow(OBSTACK, datum) \
346 1.3 christos __extension__ \
347 1.3 christos ({ struct obstack *__o = (OBSTACK); \
348 1.3 christos if (obstack_room (__o) < sizeof (void *)) \
349 1.3 christos _obstack_newchunk (__o, sizeof (void *)); \
350 1.3 christos obstack_ptr_grow_fast (__o, datum); })
351 1.3 christos
352 1.3 christos # define obstack_int_grow(OBSTACK, datum) \
353 1.3 christos __extension__ \
354 1.3 christos ({ struct obstack *__o = (OBSTACK); \
355 1.3 christos if (obstack_room (__o) < sizeof (int)) \
356 1.3 christos _obstack_newchunk (__o, sizeof (int)); \
357 1.3 christos obstack_int_grow_fast (__o, datum); })
358 1.3 christos
359 1.3 christos # define obstack_ptr_grow_fast(OBSTACK, aptr) \
360 1.3 christos __extension__ \
361 1.3 christos ({ struct obstack *__o1 = (OBSTACK); \
362 1.3 christos void *__p1 = __o1->next_free; \
363 1.3 christos *(const void **) __p1 = (aptr); \
364 1.3 christos __o1->next_free += sizeof (const void *); \
365 1.3 christos (void) 0; })
366 1.3 christos
367 1.3 christos # define obstack_int_grow_fast(OBSTACK, aint) \
368 1.3 christos __extension__ \
369 1.3 christos ({ struct obstack *__o1 = (OBSTACK); \
370 1.3 christos void *__p1 = __o1->next_free; \
371 1.3 christos *(int *) __p1 = (aint); \
372 1.3 christos __o1->next_free += sizeof (int); \
373 1.3 christos (void) 0; })
374 1.3 christos
375 1.3 christos # define obstack_blank(OBSTACK, length) \
376 1.3 christos __extension__ \
377 1.3 christos ({ struct obstack *__o = (OBSTACK); \
378 1.3 christos _OBSTACK_SIZE_T __len = (length); \
379 1.3 christos if (obstack_room (__o) < __len) \
380 1.3 christos _obstack_newchunk (__o, __len); \
381 1.3 christos obstack_blank_fast (__o, __len); })
382 1.3 christos
383 1.3 christos # define obstack_alloc(OBSTACK, length) \
384 1.3 christos __extension__ \
385 1.3 christos ({ struct obstack *__h = (OBSTACK); \
386 1.3 christos obstack_blank (__h, (length)); \
387 1.3 christos obstack_finish (__h); })
388 1.3 christos
389 1.3 christos # define obstack_copy(OBSTACK, where, length) \
390 1.3 christos __extension__ \
391 1.3 christos ({ struct obstack *__h = (OBSTACK); \
392 1.3 christos obstack_grow (__h, (where), (length)); \
393 1.3 christos obstack_finish (__h); })
394 1.3 christos
395 1.3 christos # define obstack_copy0(OBSTACK, where, length) \
396 1.3 christos __extension__ \
397 1.3 christos ({ struct obstack *__h = (OBSTACK); \
398 1.3 christos obstack_grow0 (__h, (where), (length)); \
399 1.3 christos obstack_finish (__h); })
400 1.3 christos
401 1.3 christos /* The local variable is named __o1 to avoid a shadowed variable
402 1.3 christos warning when invoked from other obstack macros, typically obstack_free. */
403 1.3 christos # define obstack_finish(OBSTACK) \
404 1.3 christos __extension__ \
405 1.3 christos ({ struct obstack *__o1 = (OBSTACK); \
406 1.3 christos void *__value = (void *) __o1->object_base; \
407 1.3 christos if (__o1->next_free == __value) \
408 1.3 christos __o1->maybe_empty_object = 1; \
409 1.3 christos __o1->next_free \
410 1.3 christos = __PTR_ALIGN (__o1->object_base, __o1->next_free, \
411 1.3 christos __o1->alignment_mask); \
412 1.3 christos if ((size_t) (__o1->next_free - (char *) __o1->chunk) \
413 1.3 christos > (size_t) (__o1->chunk_limit - (char *) __o1->chunk)) \
414 1.3 christos __o1->next_free = __o1->chunk_limit; \
415 1.3 christos __o1->object_base = __o1->next_free; \
416 1.3 christos __value; })
417 1.3 christos
418 1.3 christos # define obstack_free(OBSTACK, OBJ) \
419 1.3 christos __extension__ \
420 1.3 christos ({ struct obstack *__o = (OBSTACK); \
421 1.3 christos void *__obj = (void *) (OBJ); \
422 1.3 christos if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \
423 1.3 christos __o->next_free = __o->object_base = (char *) __obj; \
424 1.3 christos else \
425 1.3 christos _obstack_free (__o, __obj); })
426 1.3 christos
427 1.3 christos #else /* not __GNUC__ */
428 1.3 christos
429 1.3 christos # define obstack_object_size(h) \
430 1.3 christos ((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base))
431 1.3 christos
432 1.3 christos # define obstack_room(h) \
433 1.3 christos ((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free))
434 1.3 christos
435 1.3 christos # define obstack_empty_p(h) \
436 1.3 christos ((h)->chunk->prev == 0 \
437 1.3 christos && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
438 1.3 christos (h)->chunk->contents, \
439 1.3 christos (h)->alignment_mask))
440 1.1 christos
441 1.1 christos /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
442 1.1 christos so that we can avoid having void expressions
443 1.1 christos in the arms of the conditional expression.
444 1.1 christos Casting the third operand to void was tried before,
445 1.1 christos but some compilers won't accept it. */
446 1.1 christos
447 1.3 christos # define obstack_make_room(h, length) \
448 1.3 christos ((h)->temp.i = (length), \
449 1.3 christos ((obstack_room (h) < (h)->temp.i) \
450 1.3 christos ? (_obstack_newchunk (h, (h)->temp.i), 0) : 0), \
451 1.3 christos (void) 0)
452 1.3 christos
453 1.3 christos # define obstack_grow(h, where, length) \
454 1.3 christos ((h)->temp.i = (length), \
455 1.3 christos ((obstack_room (h) < (h)->temp.i) \
456 1.3 christos ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
457 1.3 christos memcpy ((h)->next_free, where, (h)->temp.i), \
458 1.3 christos (h)->next_free += (h)->temp.i, \
459 1.3 christos (void) 0)
460 1.3 christos
461 1.3 christos # define obstack_grow0(h, where, length) \
462 1.3 christos ((h)->temp.i = (length), \
463 1.3 christos ((obstack_room (h) < (h)->temp.i + 1) \
464 1.3 christos ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \
465 1.3 christos memcpy ((h)->next_free, where, (h)->temp.i), \
466 1.3 christos (h)->next_free += (h)->temp.i, \
467 1.3 christos *((h)->next_free)++ = 0, \
468 1.3 christos (void) 0)
469 1.3 christos
470 1.3 christos # define obstack_1grow(h, datum) \
471 1.3 christos (((obstack_room (h) < 1) \
472 1.3 christos ? (_obstack_newchunk ((h), 1), 0) : 0), \
473 1.3 christos obstack_1grow_fast (h, datum))
474 1.3 christos
475 1.3 christos # define obstack_ptr_grow(h, datum) \
476 1.3 christos (((obstack_room (h) < sizeof (char *)) \
477 1.3 christos ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
478 1.3 christos obstack_ptr_grow_fast (h, datum))
479 1.3 christos
480 1.3 christos # define obstack_int_grow(h, datum) \
481 1.3 christos (((obstack_room (h) < sizeof (int)) \
482 1.3 christos ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
483 1.3 christos obstack_int_grow_fast (h, datum))
484 1.3 christos
485 1.3 christos # define obstack_ptr_grow_fast(h, aptr) \
486 1.3 christos (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr), \
487 1.3 christos (void) 0)
488 1.3 christos
489 1.3 christos # define obstack_int_grow_fast(h, aint) \
490 1.3 christos (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint), \
491 1.3 christos (void) 0)
492 1.3 christos
493 1.3 christos # define obstack_blank(h, length) \
494 1.3 christos ((h)->temp.i = (length), \
495 1.3 christos ((obstack_room (h) < (h)->temp.i) \
496 1.3 christos ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
497 1.3 christos obstack_blank_fast (h, (h)->temp.i))
498 1.3 christos
499 1.3 christos # define obstack_alloc(h, length) \
500 1.3 christos (obstack_blank ((h), (length)), obstack_finish ((h)))
501 1.3 christos
502 1.3 christos # define obstack_copy(h, where, length) \
503 1.3 christos (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
504 1.3 christos
505 1.3 christos # define obstack_copy0(h, where, length) \
506 1.3 christos (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
507 1.3 christos
508 1.3 christos # define obstack_finish(h) \
509 1.3 christos (((h)->next_free == (h)->object_base \
510 1.3 christos ? (((h)->maybe_empty_object = 1), 0) \
511 1.3 christos : 0), \
512 1.3 christos (h)->temp.p = (h)->object_base, \
513 1.3 christos (h)->next_free \
514 1.3 christos = __PTR_ALIGN ((h)->object_base, (h)->next_free, \
515 1.3 christos (h)->alignment_mask), \
516 1.3 christos (((size_t) ((h)->next_free - (char *) (h)->chunk) \
517 1.3 christos > (size_t) ((h)->chunk_limit - (char *) (h)->chunk)) \
518 1.3 christos ? ((h)->next_free = (h)->chunk_limit) : 0), \
519 1.3 christos (h)->object_base = (h)->next_free, \
520 1.3 christos (h)->temp.p)
521 1.3 christos
522 1.3 christos # define obstack_free(h, obj) \
523 1.3 christos ((h)->temp.p = (void *) (obj), \
524 1.3 christos (((h)->temp.p > (void *) (h)->chunk \
525 1.3 christos && (h)->temp.p < (void *) (h)->chunk_limit) \
526 1.3 christos ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p) \
527 1.3 christos : _obstack_free ((h), (h)->temp.p)))
528 1.1 christos
529 1.3 christos #endif /* not __GNUC__ */
530 1.1 christos
531 1.1 christos #ifdef __cplusplus
532 1.3 christos } /* C++ */
533 1.1 christos #endif
534 1.1 christos
535 1.3 christos #endif /* _OBSTACK_H */
536