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