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