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